]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_query_system/src/ich/hcx.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / compiler / rustc_query_system / src / ich / hcx.rs
CommitLineData
ba9703b0 1use crate::ich;
064997fb 2
3dfed10e 3use rustc_ast as ast;
3c0e092e 4use rustc_data_structures::sorted_map::SortedMap;
5e7ed085 5use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher};
60c5eb7d 6use rustc_data_structures::sync::Lrc;
dfeec247 7use rustc_hir as hir;
ba9703b0
XL
8use rustc_hir::def_id::{DefId, LocalDefId};
9use rustc_hir::definitions::{DefPathHash, Definitions};
923072b8 10use rustc_index::vec::IndexVec;
c295e0f8 11use rustc_session::cstore::CrateStore;
ba9703b0 12use rustc_session::Session;
dfeec247
XL
13use rustc_span::source_map::SourceMap;
14use rustc_span::symbol::Symbol;
c295e0f8 15use 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 22pub 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
41pub(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 47impl<'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 160impl<'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 167impl<'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
202impl<'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 208impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {}