• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! This module contains `HashStable` implementations for various data types
2 //! from `rustc_middle::ty` in no particular order.
3 
4 use crate::middle::region;
5 use crate::mir;
6 use crate::ty;
7 use crate::ty::fast_reject::SimplifiedType;
8 use rustc_data_structures::fingerprint::Fingerprint;
9 use rustc_data_structures::fx::FxHashMap;
10 use rustc_data_structures::stable_hasher::HashingControls;
11 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
12 use rustc_query_system::ich::StableHashingContext;
13 use std::cell::RefCell;
14 
15 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T>
16 where
17     T: HashStable<StableHashingContext<'a>>,
18 {
hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher)19     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
20         thread_local! {
21             static CACHE: RefCell<FxHashMap<(usize, usize, HashingControls), Fingerprint>> =
22                 RefCell::new(Default::default());
23         }
24 
25         let hash = CACHE.with(|cache| {
26             let key = (self.as_ptr() as usize, self.len(), hcx.hashing_controls());
27             if let Some(&hash) = cache.borrow().get(&key) {
28                 return hash;
29             }
30 
31             let mut hasher = StableHasher::new();
32             (&self[..]).hash_stable(hcx, &mut hasher);
33 
34             let hash: Fingerprint = hasher.finish();
35             cache.borrow_mut().insert(key, hash);
36             hash
37         });
38 
39         hash.hash_stable(hcx, hasher);
40     }
41 }
42 
43 impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T>
44 where
45     T: HashStable<StableHashingContext<'a>>,
46 {
47     type KeyType = Fingerprint;
48 
49     #[inline]
to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint50     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
51         let mut hasher = StableHasher::new();
52         let mut hcx: StableHashingContext<'a> = hcx.clone();
53         self.hash_stable(&mut hcx, &mut hasher);
54         hasher.finish()
55     }
56 }
57 
58 impl<'a> ToStableHashKey<StableHashingContext<'a>> for SimplifiedType {
59     type KeyType = Fingerprint;
60 
61     #[inline]
to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint62     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
63         let mut hasher = StableHasher::new();
64         let mut hcx: StableHashingContext<'a> = hcx.clone();
65         self.hash_stable(&mut hcx, &mut hasher);
66         hasher.finish()
67     }
68 }
69 
70 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'tcx> {
hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher)71     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
72         self.unpack().hash_stable(hcx, hasher);
73     }
74 }
75 
76 // AllocIds get resolved to whatever they point to (to be stable)
77 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher)78     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
79         ty::tls::with_opt(|tcx| {
80             trace!("hashing {:?}", *self);
81             let tcx = tcx.expect("can't hash AllocIds during hir lowering");
82             tcx.try_get_global_alloc(*self).hash_stable(hcx, hasher);
83         });
84     }
85 }
86 
87 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
88     type KeyType = region::Scope;
89 
90     #[inline]
to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope91     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
92         *self
93     }
94 }
95