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