]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
Auto merge of #67808 - Marwes:projection_normalization_recurse, r=nikomatsakis
[rust.git] / src / librustc / ich / impls_hir.rs
1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
3
4 use crate::hir;
5 use crate::hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
6 use crate::hir::map::DefPathHash;
7 use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext};
8
9 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
10 use smallvec::SmallVec;
11 use std::mem;
12 use syntax::attr;
13
14 impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
15     #[inline]
16     fn hash_def_id(&mut self, def_id: DefId, hasher: &mut StableHasher) {
17         let hcx = self;
18         hcx.def_path_hash(def_id).hash_stable(hcx, hasher);
19     }
20
21     #[inline]
22     fn hash_hir_id(&mut self, hir_id: hir::HirId, hasher: &mut StableHasher) {
23         let hcx = self;
24         match hcx.node_id_hashing_mode {
25             NodeIdHashingMode::Ignore => {
26                 // Don't do anything.
27             }
28             NodeIdHashingMode::HashDefPath => {
29                 let hir::HirId { owner, local_id } = hir_id;
30
31                 hcx.local_def_path_hash(owner).hash_stable(hcx, hasher);
32                 local_id.hash_stable(hcx, hasher);
33             }
34         }
35     }
36
37     fn hash_body_id(&mut self, id: hir::BodyId, hasher: &mut StableHasher) {
38         let hcx = self;
39         if hcx.hash_bodies() {
40             hcx.body_resolver.body(id).hash_stable(hcx, hasher);
41         }
42     }
43
44     // The following implementations of HashStable for `ItemId`, `TraitItemId`, and
45     // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
46     // the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
47     // are used when another item in the HIR is *referenced* and we certainly
48     // want to pick up on a reference changing its target, so we hash the NodeIds
49     // in "DefPath Mode".
50
51     fn hash_item_id(&mut self, id: hir::ItemId, hasher: &mut StableHasher) {
52         let hcx = self;
53         let hir::ItemId { id } = id;
54
55         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
56             id.hash_stable(hcx, hasher);
57         })
58     }
59
60     fn hash_impl_item_id(&mut self, id: hir::ImplItemId, hasher: &mut StableHasher) {
61         let hcx = self;
62         let hir::ImplItemId { hir_id } = id;
63
64         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
65             hir_id.hash_stable(hcx, hasher);
66         })
67     }
68
69     fn hash_trait_item_id(&mut self, id: hir::TraitItemId, hasher: &mut StableHasher) {
70         let hcx = self;
71         let hir::TraitItemId { hir_id } = id;
72
73         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
74             hir_id.hash_stable(hcx, hasher);
75         })
76     }
77
78     fn hash_hir_mod(&mut self, module: &hir::Mod<'_>, hasher: &mut StableHasher) {
79         let hcx = self;
80         let hir::Mod { inner: ref inner_span, ref item_ids } = *module;
81
82         inner_span.hash_stable(hcx, hasher);
83
84         // Combining the `DefPathHash`s directly is faster than feeding them
85         // into the hasher. Because we use a commutative combine, we also don't
86         // have to sort the array.
87         let item_ids_hash = item_ids
88             .iter()
89             .map(|id| {
90                 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
91                 debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
92                 def_path_hash.0
93             })
94             .fold(Fingerprint::ZERO, |a, b| a.combine_commutative(b));
95
96         item_ids.len().hash_stable(hcx, hasher);
97         item_ids_hash.hash_stable(hcx, hasher);
98     }
99
100     fn hash_hir_expr(&mut self, expr: &hir::Expr<'_>, hasher: &mut StableHasher) {
101         self.while_hashing_hir_bodies(true, |hcx| {
102             let hir::Expr { hir_id: _, ref span, ref kind, ref attrs } = *expr;
103
104             span.hash_stable(hcx, hasher);
105             kind.hash_stable(hcx, hasher);
106             attrs.hash_stable(hcx, hasher);
107         })
108     }
109
110     fn hash_hir_ty(&mut self, ty: &hir::Ty<'_>, hasher: &mut StableHasher) {
111         self.while_hashing_hir_bodies(true, |hcx| {
112             let hir::Ty { hir_id: _, ref kind, ref span } = *ty;
113
114             kind.hash_stable(hcx, hasher);
115             span.hash_stable(hcx, hasher);
116         })
117     }
118
119     fn hash_hir_visibility_kind(
120         &mut self,
121         vis: &hir::VisibilityKind<'_>,
122         hasher: &mut StableHasher,
123     ) {
124         let hcx = self;
125         mem::discriminant(vis).hash_stable(hcx, hasher);
126         match *vis {
127             hir::VisibilityKind::Public | hir::VisibilityKind::Inherited => {
128                 // No fields to hash.
129             }
130             hir::VisibilityKind::Crate(sugar) => {
131                 sugar.hash_stable(hcx, hasher);
132             }
133             hir::VisibilityKind::Restricted { ref path, hir_id } => {
134                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
135                     hir_id.hash_stable(hcx, hasher);
136                 });
137                 path.hash_stable(hcx, hasher);
138             }
139         }
140     }
141 }
142
143 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
144     type KeyType = DefPathHash;
145
146     #[inline]
147     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
148         hcx.def_path_hash(*self)
149     }
150 }
151
152 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
153     #[inline]
154     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
155         hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
156     }
157 }
158
159 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
160     type KeyType = DefPathHash;
161
162     #[inline]
163     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
164         hcx.def_path_hash(self.to_def_id())
165     }
166 }
167
168 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
169     #[inline]
170     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
171         hcx.def_path_hash(DefId { krate: *self, index: CRATE_DEF_INDEX }).hash_stable(hcx, hasher);
172     }
173 }
174
175 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
176     type KeyType = DefPathHash;
177
178     #[inline]
179     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
180         let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
181         def_id.to_stable_hash_key(hcx)
182     }
183 }
184
185 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::ItemLocalId {
186     type KeyType = hir::ItemLocalId;
187
188     #[inline]
189     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> hir::ItemLocalId {
190         *self
191     }
192 }
193
194 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem<'_> {
195     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
196         let hir::TraitItem { hir_id: _, ident, ref attrs, ref generics, ref kind, span } = *self;
197
198         hcx.hash_hir_item_like(|hcx| {
199             ident.name.hash_stable(hcx, hasher);
200             attrs.hash_stable(hcx, hasher);
201             generics.hash_stable(hcx, hasher);
202             kind.hash_stable(hcx, hasher);
203             span.hash_stable(hcx, hasher);
204         });
205     }
206 }
207
208 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem<'_> {
209     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
210         let hir::ImplItem {
211             hir_id: _,
212             ident,
213             ref vis,
214             defaultness,
215             ref attrs,
216             ref generics,
217             ref kind,
218             span,
219         } = *self;
220
221         hcx.hash_hir_item_like(|hcx| {
222             ident.name.hash_stable(hcx, hasher);
223             vis.hash_stable(hcx, hasher);
224             defaultness.hash_stable(hcx, hasher);
225             attrs.hash_stable(hcx, hasher);
226             generics.hash_stable(hcx, hasher);
227             kind.hash_stable(hcx, hasher);
228             span.hash_stable(hcx, hasher);
229         });
230     }
231 }
232
233 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item<'_> {
234     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
235         let hir::Item { ident, ref attrs, hir_id: _, ref kind, ref vis, span } = *self;
236
237         hcx.hash_hir_item_like(|hcx| {
238             ident.name.hash_stable(hcx, hasher);
239             attrs.hash_stable(hcx, hasher);
240             kind.hash_stable(hcx, hasher);
241             vis.hash_stable(hcx, hasher);
242             span.hash_stable(hcx, hasher);
243         });
244     }
245 }
246
247 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body<'_> {
248     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
249         let hir::Body { params, value, generator_kind } = self;
250
251         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
252             params.hash_stable(hcx, hasher);
253             value.hash_stable(hcx, hasher);
254             generator_kind.hash_stable(hcx, hasher);
255         });
256     }
257 }
258
259 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
260     type KeyType = (DefPathHash, hir::ItemLocalId);
261
262     #[inline]
263     fn to_stable_hash_key(
264         &self,
265         hcx: &StableHashingContext<'a>,
266     ) -> (DefPathHash, hir::ItemLocalId) {
267         let hir::BodyId { hir_id } = *self;
268         hir_id.to_stable_hash_key(hcx)
269     }
270 }
271
272 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
273     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
274         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
275     }
276 }
277
278 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
279     type KeyType = DefPathHash;
280
281     #[inline]
282     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
283         hcx.local_def_path_hash(*self)
284     }
285 }
286
287 impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::LangItem {
288     fn hash_stable(&self, _: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
289         ::std::hash::Hash::hash(self, hasher);
290     }
291 }
292
293 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
294     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
295         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
296             let hir::TraitCandidate { def_id, import_ids } = self;
297
298             def_id.hash_stable(hcx, hasher);
299             import_ids.hash_stable(hcx, hasher);
300         });
301     }
302 }
303
304 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
305     type KeyType = (DefPathHash, SmallVec<[(DefPathHash, hir::ItemLocalId); 1]>);
306
307     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Self::KeyType {
308         let hir::TraitCandidate { def_id, import_ids } = self;
309
310         let import_keys = import_ids
311             .iter()
312             .map(|node_id| hcx.node_to_hir_id(*node_id))
313             .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner), hir_id.local_id))
314             .collect();
315         (hcx.def_path_hash(*def_id), import_keys)
316     }
317 }
318
319 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
320     fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
321         mem::discriminant(self).hash_stable(hcx, hasher);
322     }
323 }
324
325 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
326     fn hash_stable(&self, hcx: &mut StableHashingContext<'hir>, hasher: &mut StableHasher) {
327         mem::discriminant(self).hash_stable(hcx, hasher);
328     }
329 }