]>
Commit | Line | Data |
---|---|---|
ba9703b0 | 1 | use crate::ich; |
064997fb | 2 | |
3dfed10e | 3 | use rustc_ast as ast; |
3c0e092e | 4 | use rustc_data_structures::sorted_map::SortedMap; |
5e7ed085 | 5 | use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; |
60c5eb7d | 6 | use rustc_data_structures::sync::Lrc; |
dfeec247 | 7 | use rustc_hir as hir; |
ba9703b0 XL |
8 | use rustc_hir::def_id::{DefId, LocalDefId}; |
9 | use rustc_hir::definitions::{DefPathHash, Definitions}; | |
923072b8 | 10 | use rustc_index::vec::IndexVec; |
c295e0f8 | 11 | use rustc_session::cstore::CrateStore; |
ba9703b0 | 12 | use rustc_session::Session; |
dfeec247 XL |
13 | use rustc_span::source_map::SourceMap; |
14 | use rustc_span::symbol::Symbol; | |
c295e0f8 | 15 | use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData}; |
ea8adc8c | 16 | |
cc61c64b | 17 | /// This is the context state available during incr. comp. hashing. It contains |
e1599b0c XL |
18 | /// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e., |
19 | /// a reference to the `TyCtxt`) and it holds a few caches for speeding up various | |
20 | /// things (e.g., each `DefId`/`DefPath` is only hashed once). | |
ea8adc8c | 21 | #[derive(Clone)] |
0531ce1d | 22 | pub struct StableHashingContext<'a> { |
0531ce1d XL |
23 | definitions: &'a Definitions, |
24 | cstore: &'a dyn CrateStore, | |
923072b8 | 25 | source_span: &'a IndexVec<LocalDefId, Span>, |
5099ac24 | 26 | // The value of `-Z incremental-ignore-spans`. |
064997fb | 27 | // This field should only be used by `unstable_opts_incremental_ignore_span` |
5099ac24 | 28 | incremental_ignore_spans: bool, |
dfeec247 | 29 | pub(super) body_resolver: BodyResolver<'a>, |
ea8adc8c | 30 | // Very often, we are hashing something that does not need the |
e1599b0c | 31 | // `CachingSourceMapView`, so we initialize it lazily. |
b7449926 XL |
32 | raw_source_map: &'a SourceMap, |
33 | caching_source_map: Option<CachingSourceMapView<'a>>, | |
5099ac24 | 34 | pub(super) hashing_controls: HashingControls, |
cc61c64b XL |
35 | } |
36 | ||
e1599b0c XL |
37 | /// The `BodyResolver` allows mapping a `BodyId` to the corresponding `hir::Body`. |
38 | /// We could also just store a plain reference to the `hir::Crate` but we want | |
ea8adc8c XL |
39 | /// to avoid that the crate is used to get untracked access to all of the HIR. |
40 | #[derive(Clone, Copy)] | |
3c0e092e XL |
41 | pub(super) enum BodyResolver<'tcx> { |
42 | Forbidden, | |
f2b60f7d FG |
43 | Ignore, |
44 | Traverse { owner: LocalDefId, bodies: &'tcx SortedMap<hir::ItemLocalId, &'tcx hir::Body<'tcx>> }, | |
ea8adc8c | 45 | } |
cc61c64b | 46 | |
0531ce1d | 47 | impl<'a> StableHashingContext<'a> { |
0731742a | 48 | #[inline] |
f035d41b | 49 | fn new_with_or_without_spans( |
dfeec247 | 50 | sess: &'a Session, |
dfeec247 XL |
51 | definitions: &'a Definitions, |
52 | cstore: &'a dyn CrateStore, | |
923072b8 | 53 | source_span: &'a IndexVec<LocalDefId, Span>, |
f035d41b | 54 | always_ignore_spans: bool, |
dfeec247 | 55 | ) -> Self { |
f035d41b | 56 | let hash_spans_initial = |
064997fb | 57 | !always_ignore_spans && !sess.opts.unstable_opts.incremental_ignore_spans; |
ea8adc8c | 58 | |
cc61c64b | 59 | StableHashingContext { |
3c0e092e | 60 | body_resolver: BodyResolver::Forbidden, |
ea8adc8c XL |
61 | definitions, |
62 | cstore, | |
923072b8 | 63 | source_span, |
064997fb | 64 | incremental_ignore_spans: sess.opts.unstable_opts.incremental_ignore_spans, |
b7449926 XL |
65 | caching_source_map: None, |
66 | raw_source_map: sess.source_map(), | |
5e7ed085 | 67 | hashing_controls: HashingControls { hash_spans: hash_spans_initial }, |
cc61c64b XL |
68 | } |
69 | } | |
70 | ||
f035d41b XL |
71 | #[inline] |
72 | pub fn new( | |
73 | sess: &'a Session, | |
f035d41b XL |
74 | definitions: &'a Definitions, |
75 | cstore: &'a dyn CrateStore, | |
923072b8 | 76 | source_span: &'a IndexVec<LocalDefId, Span>, |
f035d41b XL |
77 | ) -> Self { |
78 | Self::new_with_or_without_spans( | |
79 | sess, | |
f035d41b XL |
80 | definitions, |
81 | cstore, | |
923072b8 | 82 | source_span, |
f035d41b XL |
83 | /*always_ignore_spans=*/ false, |
84 | ) | |
85 | } | |
86 | ||
87 | #[inline] | |
88 | pub fn ignore_spans( | |
89 | sess: &'a Session, | |
f035d41b XL |
90 | definitions: &'a Definitions, |
91 | cstore: &'a dyn CrateStore, | |
923072b8 | 92 | source_span: &'a IndexVec<LocalDefId, Span>, |
f035d41b XL |
93 | ) -> Self { |
94 | let always_ignore_spans = true; | |
923072b8 | 95 | Self::new_with_or_without_spans(sess, definitions, cstore, source_span, always_ignore_spans) |
f035d41b XL |
96 | } |
97 | ||
cc61c64b | 98 | #[inline] |
f2b60f7d FG |
99 | pub fn without_hir_bodies(&mut self, f: impl FnOnce(&mut StableHashingContext<'_>)) { |
100 | f(&mut StableHashingContext { body_resolver: BodyResolver::Ignore, ..self.clone() }); | |
3c0e092e XL |
101 | } |
102 | ||
103 | #[inline] | |
104 | pub fn with_hir_bodies( | |
105 | &mut self, | |
3c0e092e | 106 | owner: LocalDefId, |
064997fb FG |
107 | bodies: &SortedMap<hir::ItemLocalId, &hir::Body<'_>>, |
108 | f: impl FnOnce(&mut StableHashingContext<'_>), | |
3c0e092e | 109 | ) { |
064997fb | 110 | f(&mut StableHashingContext { |
f2b60f7d | 111 | body_resolver: BodyResolver::Traverse { owner, bodies }, |
064997fb FG |
112 | ..self.clone() |
113 | }); | |
cc61c64b XL |
114 | } |
115 | ||
116 | #[inline] | |
dfeec247 | 117 | pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self, hash_spans: bool, f: F) { |
5099ac24 FG |
118 | let prev_hash_spans = self.hashing_controls.hash_spans; |
119 | self.hashing_controls.hash_spans = hash_spans; | |
cc61c64b | 120 | f(self); |
5099ac24 | 121 | self.hashing_controls.hash_spans = prev_hash_spans; |
cc61c64b XL |
122 | } |
123 | ||
cc61c64b | 124 | #[inline] |
ea8adc8c | 125 | pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash { |
ba9703b0 XL |
126 | if let Some(def_id) = def_id.as_local() { |
127 | self.local_def_path_hash(def_id) | |
ea8adc8c XL |
128 | } else { |
129 | self.cstore.def_path_hash(def_id) | |
130 | } | |
131 | } | |
132 | ||
133 | #[inline] | |
ba9703b0 XL |
134 | pub fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash { |
135 | self.definitions.def_path_hash(def_id) | |
cc61c64b XL |
136 | } |
137 | ||
cc61c64b | 138 | #[inline] |
b7449926 XL |
139 | pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> { |
140 | match self.caching_source_map { | |
74b04a01 | 141 | Some(ref mut sm) => sm, |
ea8adc8c | 142 | ref mut none => { |
b7449926 | 143 | *none = Some(CachingSourceMapView::new(self.raw_source_map)); |
ea8adc8c XL |
144 | none.as_mut().unwrap() |
145 | } | |
146 | } | |
cc61c64b XL |
147 | } |
148 | ||
149 | #[inline] | |
150 | pub fn is_ignored_attr(&self, name: Symbol) -> bool { | |
923072b8 | 151 | ich::IGNORED_ATTRIBUTES.contains(&name) |
cc61c64b | 152 | } |
5099ac24 FG |
153 | |
154 | #[inline] | |
155 | pub fn hashing_controls(&self) -> HashingControls { | |
156 | self.hashing_controls.clone() | |
157 | } | |
cc61c64b XL |
158 | } |
159 | ||
0531ce1d | 160 | impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId { |
c295e0f8 | 161 | #[inline] |
74b04a01 XL |
162 | fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) { |
163 | panic!("Node IDs should not appear in incremental state"); | |
ea8adc8c XL |
164 | } |
165 | } | |
166 | ||
dfeec247 | 167 | impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { |
c295e0f8 | 168 | #[inline] |
60c5eb7d | 169 | fn hash_spans(&self) -> bool { |
5099ac24 FG |
170 | self.hashing_controls.hash_spans |
171 | } | |
172 | ||
173 | #[inline] | |
064997fb | 174 | fn unstable_opts_incremental_ignore_spans(&self) -> bool { |
5099ac24 | 175 | self.incremental_ignore_spans |
cc61c64b | 176 | } |
cc61c64b | 177 | |
3dfed10e | 178 | #[inline] |
136023e0 XL |
179 | fn def_path_hash(&self, def_id: DefId) -> DefPathHash { |
180 | self.def_path_hash(def_id) | |
5869c6ff XL |
181 | } |
182 | ||
c295e0f8 XL |
183 | #[inline] |
184 | fn def_span(&self, def_id: LocalDefId) -> Span { | |
923072b8 | 185 | self.source_span[def_id] |
c295e0f8 XL |
186 | } |
187 | ||
188 | #[inline] | |
5869c6ff XL |
189 | fn span_data_to_lines_and_cols( |
190 | &mut self, | |
191 | span: &SpanData, | |
192 | ) -> Option<(Lrc<SourceFile>, usize, BytePos, usize, BytePos)> { | |
193 | self.source_map().span_data_to_lines_and_cols(span) | |
194 | } | |
5099ac24 FG |
195 | |
196 | #[inline] | |
197 | fn hashing_controls(&self) -> HashingControls { | |
198 | self.hashing_controls.clone() | |
199 | } | |
b7449926 XL |
200 | } |
201 | ||
04454e1e FG |
202 | impl<'a> rustc_data_structures::intern::InternedHashingContext for StableHashingContext<'a> { |
203 | fn with_def_path_and_no_spans(&mut self, f: impl FnOnce(&mut Self)) { | |
204 | self.while_hashing_spans(false, f); | |
205 | } | |
206 | } | |
207 | ||
c295e0f8 | 208 | impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {} |