]>
Commit | Line | Data |
---|---|---|
ba9703b0 | 1 | use crate::ich; |
064997fb | 2 | |
3dfed10e | 3 | use rustc_ast as ast; |
5e7ed085 | 4 | use rustc_data_structures::stable_hasher::{HashStable, HashingControls, StableHasher}; |
60c5eb7d | 5 | use rustc_data_structures::sync::Lrc; |
ba9703b0 | 6 | use rustc_hir::def_id::{DefId, LocalDefId}; |
9c376795 FG |
7 | use rustc_hir::definitions::DefPathHash; |
8 | use rustc_session::cstore::Untracked; | |
ba9703b0 | 9 | use rustc_session::Session; |
dfeec247 XL |
10 | use rustc_span::source_map::SourceMap; |
11 | use rustc_span::symbol::Symbol; | |
2b03887a | 12 | use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData, DUMMY_SP}; |
ea8adc8c | 13 | |
cc61c64b | 14 | /// This is the context state available during incr. comp. hashing. It contains |
e1599b0c XL |
15 | /// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e., |
16 | /// a reference to the `TyCtxt`) and it holds a few caches for speeding up various | |
17 | /// things (e.g., each `DefId`/`DefPath` is only hashed once). | |
ea8adc8c | 18 | #[derive(Clone)] |
0531ce1d | 19 | pub struct StableHashingContext<'a> { |
9c376795 | 20 | untracked: &'a Untracked, |
5099ac24 | 21 | // The value of `-Z incremental-ignore-spans`. |
064997fb | 22 | // This field should only be used by `unstable_opts_incremental_ignore_span` |
5099ac24 | 23 | incremental_ignore_spans: bool, |
ea8adc8c | 24 | // Very often, we are hashing something that does not need the |
e1599b0c | 25 | // `CachingSourceMapView`, so we initialize it lazily. |
b7449926 XL |
26 | raw_source_map: &'a SourceMap, |
27 | caching_source_map: Option<CachingSourceMapView<'a>>, | |
4b012472 | 28 | hashing_controls: HashingControls, |
cc61c64b XL |
29 | } |
30 | ||
0531ce1d | 31 | impl<'a> StableHashingContext<'a> { |
0731742a | 32 | #[inline] |
9c376795 | 33 | pub fn new(sess: &'a Session, untracked: &'a Untracked) -> Self { |
487cf647 | 34 | let hash_spans_initial = !sess.opts.unstable_opts.incremental_ignore_spans; |
ea8adc8c | 35 | |
cc61c64b | 36 | StableHashingContext { |
9c376795 | 37 | untracked, |
064997fb | 38 | incremental_ignore_spans: sess.opts.unstable_opts.incremental_ignore_spans, |
b7449926 XL |
39 | caching_source_map: None, |
40 | raw_source_map: sess.source_map(), | |
5e7ed085 | 41 | hashing_controls: HashingControls { hash_spans: hash_spans_initial }, |
cc61c64b XL |
42 | } |
43 | } | |
44 | ||
cc61c64b | 45 | #[inline] |
dfeec247 | 46 | pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self, hash_spans: bool, f: F) { |
5099ac24 FG |
47 | let prev_hash_spans = self.hashing_controls.hash_spans; |
48 | self.hashing_controls.hash_spans = hash_spans; | |
cc61c64b | 49 | f(self); |
5099ac24 | 50 | self.hashing_controls.hash_spans = prev_hash_spans; |
cc61c64b XL |
51 | } |
52 | ||
cc61c64b | 53 | #[inline] |
ea8adc8c | 54 | pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash { |
ba9703b0 XL |
55 | if let Some(def_id) = def_id.as_local() { |
56 | self.local_def_path_hash(def_id) | |
ea8adc8c | 57 | } else { |
9ffffee4 | 58 | self.untracked.cstore.read().def_path_hash(def_id) |
ea8adc8c XL |
59 | } |
60 | } | |
61 | ||
62 | #[inline] | |
ba9703b0 | 63 | pub fn local_def_path_hash(&self, def_id: LocalDefId) -> DefPathHash { |
9c376795 | 64 | self.untracked.definitions.read().def_path_hash(def_id) |
cc61c64b XL |
65 | } |
66 | ||
cc61c64b | 67 | #[inline] |
b7449926 XL |
68 | pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> { |
69 | match self.caching_source_map { | |
74b04a01 | 70 | Some(ref mut sm) => sm, |
ea8adc8c | 71 | ref mut none => { |
b7449926 | 72 | *none = Some(CachingSourceMapView::new(self.raw_source_map)); |
ea8adc8c XL |
73 | none.as_mut().unwrap() |
74 | } | |
75 | } | |
cc61c64b XL |
76 | } |
77 | ||
78 | #[inline] | |
79 | pub fn is_ignored_attr(&self, name: Symbol) -> bool { | |
923072b8 | 80 | ich::IGNORED_ATTRIBUTES.contains(&name) |
cc61c64b | 81 | } |
5099ac24 FG |
82 | |
83 | #[inline] | |
84 | pub fn hashing_controls(&self) -> HashingControls { | |
85 | self.hashing_controls.clone() | |
86 | } | |
cc61c64b XL |
87 | } |
88 | ||
0531ce1d | 89 | impl<'a> HashStable<StableHashingContext<'a>> for ast::NodeId { |
c295e0f8 | 90 | #[inline] |
74b04a01 XL |
91 | fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) { |
92 | panic!("Node IDs should not appear in incremental state"); | |
ea8adc8c XL |
93 | } |
94 | } | |
95 | ||
dfeec247 | 96 | impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { |
c295e0f8 | 97 | #[inline] |
60c5eb7d | 98 | fn hash_spans(&self) -> bool { |
5099ac24 FG |
99 | self.hashing_controls.hash_spans |
100 | } | |
101 | ||
102 | #[inline] | |
064997fb | 103 | fn unstable_opts_incremental_ignore_spans(&self) -> bool { |
5099ac24 | 104 | self.incremental_ignore_spans |
cc61c64b | 105 | } |
cc61c64b | 106 | |
3dfed10e | 107 | #[inline] |
136023e0 XL |
108 | fn def_path_hash(&self, def_id: DefId) -> DefPathHash { |
109 | self.def_path_hash(def_id) | |
5869c6ff XL |
110 | } |
111 | ||
c295e0f8 XL |
112 | #[inline] |
113 | fn def_span(&self, def_id: LocalDefId) -> Span { | |
9ffffee4 | 114 | self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP) |
c295e0f8 XL |
115 | } |
116 | ||
117 | #[inline] | |
5869c6ff XL |
118 | fn span_data_to_lines_and_cols( |
119 | &mut self, | |
120 | span: &SpanData, | |
121 | ) -> Option<(Lrc<SourceFile>, usize, BytePos, usize, BytePos)> { | |
122 | self.source_map().span_data_to_lines_and_cols(span) | |
123 | } | |
5099ac24 FG |
124 | |
125 | #[inline] | |
126 | fn hashing_controls(&self) -> HashingControls { | |
127 | self.hashing_controls.clone() | |
128 | } | |
b7449926 XL |
129 | } |
130 | ||
c295e0f8 | 131 | impl<'a> rustc_session::HashStableContext for StableHashingContext<'a> {} |