1 //! This module contains `HashStable` implementations for various HIR data
2 //! types in no particular order.
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};
9 use rustc_data_structures::stable_hasher::{
10 HashStable, ToStableHashKey, StableHasher, StableHasherResult,
12 use smallvec::SmallVec;
17 impl<'a> HashStable<StableHashingContext<'a>> for DefId {
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);
26 impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
27 type KeyType = DefPathHash;
30 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
31 hcx.def_path_hash(*self)
35 impl<'a> HashStable<StableHashingContext<'a>> for LocalDefId {
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);
44 impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalDefId {
45 type KeyType = DefPathHash;
48 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
49 hcx.def_path_hash(self.to_def_id())
53 impl<'a> HashStable<StableHashingContext<'a>> for CrateNum {
55 fn hash_stable<W: StableHasherResult>(&self,
56 hcx: &mut StableHashingContext<'a>,
57 hasher: &mut StableHasher<W>) {
58 hcx.def_path_hash(DefId {
60 index: CRATE_DEF_INDEX
61 }).hash_stable(hcx, hasher);
65 impl<'a> ToStableHashKey<StableHashingContext<'a>> for CrateNum {
66 type KeyType = DefPathHash;
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)
75 impl<'a> ToStableHashKey<StableHashingContext<'a>>
76 for hir::ItemLocalId {
77 type KeyType = hir::ItemLocalId;
80 fn to_stable_hash_key(&self,
81 _: &StableHashingContext<'a>)
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
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>) {
102 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
103 id.hash_stable(hcx, hasher);
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 {
116 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
117 hir_id.hash_stable(hcx, hasher);
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 {
130 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
131 hir_id.hash_stable(hcx, hasher);
136 impl_stable_hash_for!(struct ast::Label {
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| {
151 kind.hash_stable(hcx, hasher);
152 span.hash_stable(hcx, hasher);
157 impl_stable_hash_for_spanned!(hir::BinOpKind);
159 impl_stable_hash_for!(struct hir::Stmt {
166 impl_stable_hash_for_spanned!(ast::Name);
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| {
180 span.hash_stable(hcx, hasher);
181 kind.hash_stable(hcx, hasher);
182 attrs.hash_stable(hcx, hasher);
187 impl_stable_hash_for_spanned!(usize);
189 impl_stable_hash_for!(struct ast::Ident {
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>) {
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);
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>) {
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);
245 impl_stable_hash_for!(enum ast::CrateSugar {
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);
256 hir::VisibilityKind::Public |
257 hir::VisibilityKind::Inherited => {
258 // No fields to hash.
260 hir::VisibilityKind::Crate(sugar) => {
261 sugar.hash_stable(hcx, hasher);
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);
267 path.hash_stable(hcx, hasher);
273 impl_stable_hash_for_spanned!(hir::VisibilityKind);
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>) {
280 inner: ref inner_span,
284 inner_span.hash_stable(hcx, hasher);
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
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));
295 }).fold(Fingerprint::ZERO, |a, b| {
296 a.combine_commutative(b)
299 item_ids.len().hash_stable(hcx, hasher);
300 item_ids_hash.hash_stable(hcx, hasher);
304 impl_stable_hash_for_spanned!(hir::Variant);
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>) {
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);
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>) {
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);
348 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::BodyId {
349 type KeyType = (DefPathHash, hir::ItemLocalId);
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)
360 impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
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);
369 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
370 type KeyType = DefPathHash;
373 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> DefPathHash {
374 hcx.local_def_path_hash(*self)
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);
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 {
396 def_id.hash_stable(hcx, hasher);
397 import_ids.hash_stable(hcx, hasher);
402 impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::TraitCandidate {
403 type KeyType = (DefPathHash, SmallVec<[(DefPathHash, hir::ItemLocalId); 1]>);
405 fn to_stable_hash_key(&self,
406 hcx: &StableHashingContext<'a>)
408 let hir::TraitCandidate {
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)
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);
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);