1 //! This module contains `HashStable` implementations for various data types
2 //! from rustc::ty in no particular order.
4 use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode};
5 use rustc_data_structures::fx::FxHashMap;
6 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
7 StableHasher, StableHasherResult};
8 use std::cell::RefCell;
10 use crate::middle::region;
14 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T>
16 T: HashStable<StableHashingContext<'a>>,
18 fn hash_stable<W: StableHasherResult>(&self,
19 hcx: &mut StableHashingContext<'a>,
20 hasher: &mut StableHasher<W>) {
22 static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
23 RefCell::new(Default::default());
26 let hash = CACHE.with(|cache| {
27 let key = (self.as_ptr() as usize, self.len());
28 if let Some(&hash) = cache.borrow().get(&key) {
32 let mut hasher = StableHasher::new();
33 (&self[..]).hash_stable(hcx, &mut hasher);
35 let hash: Fingerprint = hasher.finish();
36 cache.borrow_mut().insert(key, hash);
40 hash.hash_stable(hcx, hasher);
44 impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T>
46 T: HashStable<StableHashingContext<'a>>,
48 type KeyType = Fingerprint;
51 fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
52 let mut hasher = StableHasher::new();
53 let mut hcx: StableHashingContext<'a> = hcx.clone();
54 self.hash_stable(&mut hcx, &mut hasher);
59 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'tcx> {
60 fn hash_stable<W: StableHasherResult>(&self,
61 hcx: &mut StableHashingContext<'a>,
62 hasher: &mut StableHasher<W>) {
63 self.unpack().hash_stable(hcx, hasher);
67 impl<'a> HashStable<StableHashingContext<'a>>
69 fn hash_stable<W: StableHasherResult>(&self,
70 hcx: &mut StableHashingContext<'a>,
71 hasher: &mut StableHasher<W>) {
72 mem::discriminant(self).hash_stable(hcx, hasher);
77 // No variant fields to hash for these ...
79 ty::ReLateBound(db, ty::BrAnon(i)) => {
80 db.hash_stable(hcx, hasher);
81 i.hash_stable(hcx, hasher);
83 ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
84 db.hash_stable(hcx, hasher);
85 def_id.hash_stable(hcx, hasher);
86 name.hash_stable(hcx, hasher);
88 ty::ReLateBound(db, ty::BrEnv) => {
89 db.hash_stable(hcx, hasher);
91 ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
92 def_id.hash_stable(hcx, hasher);
93 index.hash_stable(hcx, hasher);
94 name.hash_stable(hcx, hasher);
96 ty::ReScope(scope) => {
97 scope.hash_stable(hcx, hasher);
99 ty::ReFree(ref free_region) => {
100 free_region.hash_stable(hcx, hasher);
102 ty::ReClosureBound(vid) => {
103 vid.hash_stable(hcx, hasher);
106 ty::RePlaceholder(..) => {
107 bug!("StableHasher: unexpected region {:?}", *self)
113 impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
115 fn hash_stable<W: StableHasherResult>(&self,
116 hcx: &mut StableHashingContext<'a>,
117 hasher: &mut StableHasher<W>) {
118 self.index().hash_stable(hcx, hasher);
122 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> {
124 fn hash_stable<W: StableHasherResult>(
126 hcx: &mut StableHashingContext<'a>,
127 hasher: &mut StableHasher<W>,
129 self.index.hash_stable(hcx, hasher);
133 impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar {
135 fn hash_stable<W: StableHasherResult>(
137 hcx: &mut StableHashingContext<'tcx>,
138 hasher: &mut StableHasher<W>,
140 self.index().hash_stable(hcx, hasher);
144 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
146 T: HashStable<StableHashingContext<'a>>,
148 fn hash_stable<W: StableHasherResult>(&self,
149 hcx: &mut StableHashingContext<'a>,
150 hasher: &mut StableHasher<W>) {
151 self.skip_binder().hash_stable(hcx, hasher);
155 // AllocIds get resolved to whatever they point to (to be stable)
156 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
157 fn hash_stable<W: StableHasherResult>(
159 hcx: &mut StableHashingContext<'a>,
160 hasher: &mut StableHasher<W>,
162 ty::tls::with_opt(|tcx| {
163 trace!("hashing {:?}", *self);
164 let tcx = tcx.expect("can't hash AllocIds during hir lowering");
165 let alloc_kind = tcx.alloc_map.lock().get(*self);
166 alloc_kind.hash_stable(hcx, hasher);
171 // Allocations treat their relocations specially
172 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
173 fn hash_stable<W: StableHasherResult>(
175 hcx: &mut StableHashingContext<'a>,
176 hasher: &mut StableHasher<W>,
178 let mir::interpret::Allocation {
179 bytes, relocations, undef_mask, align, mutability,
182 bytes.hash_stable(hcx, hasher);
183 relocations.len().hash_stable(hcx, hasher);
184 for reloc in relocations.iter() {
185 reloc.hash_stable(hcx, hasher);
187 undef_mask.hash_stable(hcx, hasher);
188 align.hash_stable(hcx, hasher);
189 mutability.hash_stable(hcx, hasher);
193 impl_stable_hash_for!(enum ::syntax::ast::Mutability {
198 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
199 type KeyType = region::Scope;
202 fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
207 impl<'a> HashStable<StableHashingContext<'a>> for ty::TyVid {
208 fn hash_stable<W: StableHasherResult>(&self,
209 _hcx: &mut StableHashingContext<'a>,
210 _hasher: &mut StableHasher<W>) {
211 // TyVid values are confined to an inference context and hence
212 // should not be hashed.
213 bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
217 impl<'a> HashStable<StableHashingContext<'a>> for ty::IntVid {
218 fn hash_stable<W: StableHasherResult>(&self,
219 _hcx: &mut StableHashingContext<'a>,
220 _hasher: &mut StableHasher<W>) {
221 // IntVid values are confined to an inference context and hence
222 // should not be hashed.
223 bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
227 impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
228 fn hash_stable<W: StableHasherResult>(&self,
229 _hcx: &mut StableHashingContext<'a>,
230 _hasher: &mut StableHasher<W>) {
231 // FloatVid values are confined to an inference context and hence
232 // should not be hashed.
233 bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
237 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
239 T: HashStable<StableHashingContext<'a>>,
241 fn hash_stable<W: StableHasherResult>(&self,
242 hcx: &mut StableHashingContext<'a>,
243 hasher: &mut StableHasher<W>) {
244 self.borrow().hash_stable(hcx, hasher);
248 impl<'a> HashStable<StableHashingContext<'a>>
249 for crate::middle::privacy::AccessLevels {
250 fn hash_stable<W: StableHasherResult>(&self,
251 hcx: &mut StableHashingContext<'a>,
252 hasher: &mut StableHasher<W>) {
253 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
254 let crate::middle::privacy::AccessLevels {
258 map.hash_stable(hcx, hasher);