]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_hir.rs
Rename `Stmt.node` to `Stmt.kind`
[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::map::DefPathHash;
6 use crate::hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
7 use crate::ich::{StableHashingContext, NodeIdHashingMode, Fingerprint};
8
9 use rustc_data_structures::stable_hasher::{
10     HashStable, ToStableHashKey, StableHasher, StableHasherResult,
11 };
12 use smallvec::SmallVec;
13 use std::mem;
14 use syntax::ast;
15 use syntax::attr;
16
17 impl<'a> HashStable<StableHashingContext<'a>> for DefId {
18     #[inline]
19     fn hash_stable<W: StableHasherResult>(&self,
20                                           hcx: &mut StableHashingContext<'a>,
21                                           hasher: &mut StableHasher<W>) {
22         hcx.def_path_hash(*self).hash_stable(hcx, hasher);
23     }
24 }
25
26 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
27     type KeyType = DefPathHash;
28
29     #[inline]
30     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
31         hcx.def_path_hash(*self)
32     }
33 }
34
35 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
36     #[inline]
37     fn hash_stable<W: StableHasherResult>(&self,
38                                           hcx: &mut StableHashingContext<'a>,
39                                           hasher: &mut StableHasher<W>) {
40         hcx.def_path_hash(self.to_def_id()).hash_stable(hcx, hasher);
41     }
42 }
43
44 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
45     type KeyType = DefPathHash;
46
47     #[inline]
48     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
49         hcx.def_path_hash(self.to_def_id())
50     }
51 }
52
53 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
54     #[inline]
55     fn hash_stable<W: StableHasherResult>(&self,
56                                           hcx: &mut StableHashingContext<'a>,
57                                           hasher: &mut StableHasher<W>) {
58         hcx.def_path_hash(DefId {
59             krate: *self,
60             index: CRATE_DEF_INDEX
61         }).hash_stable(hcx, hasher);
62     }
63 }
64
65 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
66     type KeyType = DefPathHash;
67
68     #[inline]
69     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
70         let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
71         def_id.to_stable_hash_key(hcx)
72     }
73 }
74
75 impl<'a> ToStableHashKey<StableHashingContext<'a>>
76 for hir::ItemLocalId {
77     type KeyType = hir::ItemLocalId;
78
79     #[inline]
80     fn to_stable_hash_key(&self,
81                           _: &StableHashingContext<'a>)
82                           -> hir::ItemLocalId {
83         *self
84     }
85 }
86
87 // The following implementations of HashStable for `ItemId`, `TraitItemId`, and
88 // `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
89 // the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
90 // are used when another item in the HIR is *referenced* and we certainly
91 // want to pick up on a reference changing its target, so we hash the NodeIds
92 // in "DefPath Mode".
93
94 impl<'a> HashStable<StableHashingContext<'a>> for hir::ItemId {
95     fn hash_stable<W: StableHasherResult>(&self,
96                                           hcx: &mut StableHashingContext<'a>,
97                                           hasher: &mut StableHasher<W>) {
98         let hir::ItemId {
99             id
100         } = *self;
101
102         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
103             id.hash_stable(hcx, hasher);
104         })
105     }
106 }
107
108 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItemId {
109     fn hash_stable<W: StableHasherResult>(&self,
110                                           hcx: &mut StableHashingContext<'a>,
111                                           hasher: &mut StableHasher<W>) {
112         let hir::TraitItemId {
113             hir_id
114         } = * self;
115
116         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
117             hir_id.hash_stable(hcx, hasher);
118         })
119     }
120 }
121
122 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
123     fn hash_stable<W: StableHasherResult>(&self,
124                                           hcx: &mut StableHashingContext<'a>,
125                                           hasher: &mut StableHasher<W>) {
126         let hir::ImplItemId {
127             hir_id
128         } = * self;
129
130         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
131             hir_id.hash_stable(hcx, hasher);
132         })
133     }
134 }
135
136 impl_stable_hash_for!(struct ast::Label {
137     ident
138 });
139
140 impl<'a> HashStable<StableHashingContext<'a>> for hir::Ty {
141     fn hash_stable<W: StableHasherResult>(&self,
142                                           hcx: &mut StableHashingContext<'a>,
143                                           hasher: &mut StableHasher<W>) {
144         hcx.while_hashing_hir_bodies(true, |hcx| {
145             let hir::Ty {
146                 hir_id: _,
147                 ref kind,
148                 ref span,
149             } = *self;
150
151             kind.hash_stable(hcx, hasher);
152             span.hash_stable(hcx, hasher);
153         })
154     }
155 }
156
157 impl_stable_hash_for_spanned!(hir::BinOpKind);
158
159 impl_stable_hash_for!(struct hir::Stmt {
160     hir_id,
161     kind,
162     span,
163 });
164
165
166 impl_stable_hash_for_spanned!(ast::Name);
167
168 impl<'a> HashStable<StableHashingContext<'a>> for hir::Expr {
169     fn hash_stable<W: StableHasherResult>(&self,
170                                           hcx: &mut StableHashingContext<'a>,
171                                           hasher: &mut StableHasher<W>) {
172         hcx.while_hashing_hir_bodies(true, |hcx| {
173             let hir::Expr {
174                 hir_id: _,
175                 ref span,
176                 ref kind,
177                 ref attrs
178             } = *self;
179
180             span.hash_stable(hcx, hasher);
181             kind.hash_stable(hcx, hasher);
182             attrs.hash_stable(hcx, hasher);
183         })
184     }
185 }
186
187 impl_stable_hash_for_spanned!(usize);
188
189 impl_stable_hash_for!(struct ast::Ident {
190     name,
191     span,
192 });
193
194 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitItem {
195     fn hash_stable<W: StableHasherResult>(&self,
196                                           hcx: &mut StableHashingContext<'a>,
197                                           hasher: &mut StableHasher<W>) {
198         let hir::TraitItem {
199             hir_id: _,
200             ident,
201             ref attrs,
202             ref generics,
203             ref kind,
204             span
205         } = *self;
206
207         hcx.hash_hir_item_like(|hcx| {
208             ident.name.hash_stable(hcx, hasher);
209             attrs.hash_stable(hcx, hasher);
210             generics.hash_stable(hcx, hasher);
211             kind.hash_stable(hcx, hasher);
212             span.hash_stable(hcx, hasher);
213         });
214     }
215 }
216
217
218 impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
219     fn hash_stable<W: StableHasherResult>(&self,
220                                           hcx: &mut StableHashingContext<'a>,
221                                           hasher: &mut StableHasher<W>) {
222         let hir::ImplItem {
223             hir_id: _,
224             ident,
225             ref vis,
226             defaultness,
227             ref attrs,
228             ref generics,
229             ref kind,
230             span
231         } = *self;
232
233         hcx.hash_hir_item_like(|hcx| {
234             ident.name.hash_stable(hcx, hasher);
235             vis.hash_stable(hcx, hasher);
236             defaultness.hash_stable(hcx, hasher);
237             attrs.hash_stable(hcx, hasher);
238             generics.hash_stable(hcx, hasher);
239             kind.hash_stable(hcx, hasher);
240             span.hash_stable(hcx, hasher);
241         });
242     }
243 }
244
245 impl_stable_hash_for!(enum ast::CrateSugar {
246     JustCrate,
247     PubCrate,
248 });
249
250 impl<'a> HashStable<StableHashingContext<'a>> for hir::VisibilityKind {
251     fn hash_stable<W: StableHasherResult>(&self,
252                                           hcx: &mut StableHashingContext<'a>,
253                                           hasher: &mut StableHasher<W>) {
254         mem::discriminant(self).hash_stable(hcx, hasher);
255         match *self {
256             hir::VisibilityKind::Public |
257             hir::VisibilityKind::Inherited => {
258                 // No fields to hash.
259             }
260             hir::VisibilityKind::Crate(sugar) => {
261                 sugar.hash_stable(hcx, hasher);
262             }
263             hir::VisibilityKind::Restricted { ref path, hir_id } => {
264                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
265                     hir_id.hash_stable(hcx, hasher);
266                 });
267                 path.hash_stable(hcx, hasher);
268             }
269         }
270     }
271 }
272
273 impl_stable_hash_for_spanned!(hir::VisibilityKind);
274
275 impl<'a> HashStable<StableHashingContext<'a>> for hir::Mod {
276     fn hash_stable<W: StableHasherResult>(&self,
277                                           hcx: &mut StableHashingContext<'a>,
278                                           hasher: &mut StableHasher<W>) {
279         let hir::Mod {
280             inner: ref inner_span,
281             ref item_ids,
282         } = *self;
283
284         inner_span.hash_stable(hcx, hasher);
285
286         // Combining the `DefPathHash`s directly is faster than feeding them
287         // into the hasher. Because we use a commutative combine, we also don't
288         // have to sort the array.
289         let item_ids_hash = item_ids
290             .iter()
291             .map(|id| {
292                 let (def_path_hash, local_id) = id.id.to_stable_hash_key(hcx);
293                 debug_assert_eq!(local_id, hir::ItemLocalId::from_u32(0));
294                 def_path_hash.0
295             }).fold(Fingerprint::ZERO, |a, b| {
296                 a.combine_commutative(b)
297             });
298
299         item_ids.len().hash_stable(hcx, hasher);
300         item_ids_hash.hash_stable(hcx, hasher);
301     }
302 }
303
304 impl_stable_hash_for_spanned!(hir::Variant);
305
306
307 impl<'a> HashStable<StableHashingContext<'a>> for hir::Item {
308     fn hash_stable<W: StableHasherResult>(&self,
309                                           hcx: &mut StableHashingContext<'a>,
310                                           hasher: &mut StableHasher<W>) {
311         let hir::Item {
312             ident,
313             ref attrs,
314             hir_id: _,
315             ref node,
316             ref vis,
317             span
318         } = *self;
319
320         hcx.hash_hir_item_like(|hcx| {
321             ident.name.hash_stable(hcx, hasher);
322             attrs.hash_stable(hcx, hasher);
323             node.hash_stable(hcx, hasher);
324             vis.hash_stable(hcx, hasher);
325             span.hash_stable(hcx, hasher);
326         });
327     }
328 }
329
330 impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
331     fn hash_stable<W: StableHasherResult>(&self,
332                                           hcx: &mut StableHashingContext<'a>,
333                                           hasher: &mut StableHasher<W>) {
334         let hir::Body {
335             params,
336             value,
337             generator_kind,
338         } = self;
339
340         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
341             params.hash_stable(hcx, hasher);
342             value.hash_stable(hcx, hasher);
343             generator_kind.hash_stable(hcx, hasher);
344         });
345     }
346 }
347
348 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
349     type KeyType = (DefPathHash, hir::ItemLocalId);
350
351     #[inline]
352     fn to_stable_hash_key(&self,
353                           hcx: &StableHashingContext<'a>)
354                           -> (DefPathHash, hir::ItemLocalId) {
355         let hir::BodyId { hir_id } = *self;
356         hir_id.to_stable_hash_key(hcx)
357     }
358 }
359
360 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
361
362     fn hash_stable<W: StableHasherResult>(&self,
363                                           hcx: &mut StableHashingContext<'a>,
364                                           hasher: &mut StableHasher<W>) {
365         hcx.local_def_path_hash(*self).hash_stable(hcx, hasher);
366     }
367 }
368
369 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
370     type KeyType = DefPathHash;
371
372     #[inline]
373     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
374          hcx.local_def_path_hash(*self)
375     }
376 }
377
378 impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::LangItem {
379     fn hash_stable<W: StableHasherResult>(&self,
380                                           _: &mut StableHashingContext<'a>,
381                                           hasher: &mut StableHasher<W>) {
382         ::std::hash::Hash::hash(self, hasher);
383     }
384 }
385
386 impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
387     fn hash_stable<W: StableHasherResult>(&self,
388                                           hcx: &mut StableHashingContext<'a>,
389                                           hasher: &mut StableHasher<W>) {
390         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
391             let hir::TraitCandidate {
392                 def_id,
393                 import_ids,
394             } = self;
395
396             def_id.hash_stable(hcx, hasher);
397             import_ids.hash_stable(hcx, hasher);
398         });
399     }
400 }
401
402 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
403     type KeyType = (DefPathHash, SmallVec<[(DefPathHash, hir::ItemLocalId); 1]>);
404
405     fn to_stable_hash_key(&self,
406                           hcx: &StableHashingContext<'a>)
407                           -> Self::KeyType {
408         let hir::TraitCandidate {
409             def_id,
410             import_ids,
411         } = self;
412
413         let import_keys = import_ids.iter().map(|node_id| hcx.node_to_hir_id(*node_id))
414                                            .map(|hir_id| (hcx.local_def_path_hash(hir_id.owner),
415                                                           hir_id.local_id)).collect();
416         (hcx.def_path_hash(*def_id), import_keys)
417     }
418 }
419
420 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::InlineAttr {
421     fn hash_stable<W: StableHasherResult>(&self,
422                                           hcx: &mut StableHashingContext<'hir>,
423                                           hasher: &mut StableHasher<W>) {
424         mem::discriminant(self).hash_stable(hcx, hasher);
425     }
426 }
427
428 impl<'hir> HashStable<StableHashingContext<'hir>> for attr::OptimizeAttr {
429     fn hash_stable<W: StableHasherResult>(&self,
430                                           hcx: &mut StableHashingContext<'hir>,
431                                           hasher: &mut StableHasher<W>) {
432         mem::discriminant(self).hash_stable(hcx, hasher);
433     }
434 }