]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_ty.rs
Further reduce the likelyhood of hash collisions
[rust.git] / src / librustc / ich / impls_ty.rs
1 //! This module contains `HashStable` implementations for various data types
2 //! from rustc::ty in no particular order.
3
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;
9 use std::mem;
10 use crate::middle::region;
11 use crate::ty;
12 use crate::mir;
13
14 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T>
15 where
16     T: HashStable<StableHashingContext<'a>>,
17 {
18     fn hash_stable<W: StableHasherResult>(&self,
19                                           hcx: &mut StableHashingContext<'a>,
20                                           hasher: &mut StableHasher<W>) {
21         thread_local! {
22             static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
23                 RefCell::new(Default::default());
24         }
25
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) {
29                 return hash;
30             }
31
32             let mut hasher = StableHasher::new();
33             (&self[..]).hash_stable(hcx, &mut hasher);
34
35             let hash: Fingerprint = hasher.finish();
36             cache.borrow_mut().insert(key, hash);
37             hash
38         });
39
40         hash.hash_stable(hcx, hasher);
41     }
42 }
43
44 impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T>
45 where
46     T: HashStable<StableHashingContext<'a>>,
47 {
48     type KeyType = Fingerprint;
49
50     #[inline]
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);
55         hasher.finish()
56     }
57 }
58
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);
64     }
65 }
66
67 impl<'a> HashStable<StableHashingContext<'a>>
68 for ty::RegionKind {
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);
73         match *self {
74             ty::ReErased |
75             ty::ReStatic |
76             ty::ReEmpty => {
77                 // No variant fields to hash for these ...
78             }
79             ty::ReLateBound(db, ty::BrAnon(i)) => {
80                 db.hash_stable(hcx, hasher);
81                 i.hash_stable(hcx, hasher);
82             }
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);
87             }
88             ty::ReLateBound(db, ty::BrEnv) => {
89                 db.hash_stable(hcx, hasher);
90             }
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);
95             }
96             ty::ReScope(scope) => {
97                 scope.hash_stable(hcx, hasher);
98             }
99             ty::ReFree(ref free_region) => {
100                 free_region.hash_stable(hcx, hasher);
101             }
102             ty::ReClosureBound(vid) => {
103                 vid.hash_stable(hcx, hasher);
104             }
105             ty::ReVar(..) |
106             ty::RePlaceholder(..) => {
107                 bug!("StableHasher: unexpected region {:?}", *self)
108             }
109         }
110     }
111 }
112
113 impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
114     #[inline]
115     fn hash_stable<W: StableHasherResult>(&self,
116                                           hcx: &mut StableHashingContext<'a>,
117                                           hasher: &mut StableHasher<W>) {
118         self.index().hash_stable(hcx, hasher);
119     }
120 }
121
122 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> {
123     #[inline]
124     fn hash_stable<W: StableHasherResult>(
125         &self,
126         hcx: &mut StableHashingContext<'a>,
127         hasher: &mut StableHasher<W>,
128     ) {
129         self.index.hash_stable(hcx, hasher);
130     }
131 }
132
133 impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar {
134     #[inline]
135     fn hash_stable<W: StableHasherResult>(
136         &self,
137         hcx: &mut StableHashingContext<'tcx>,
138         hasher: &mut StableHasher<W>,
139     ) {
140         self.index().hash_stable(hcx, hasher);
141     }
142 }
143
144 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
145 where
146     T: HashStable<StableHashingContext<'a>>,
147 {
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);
152     }
153 }
154
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>(
158         &self,
159         hcx: &mut StableHashingContext<'a>,
160         hasher: &mut StableHasher<W>,
161     ) {
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);
167         });
168     }
169 }
170
171 // Allocations treat their relocations specially
172 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
173     fn hash_stable<W: StableHasherResult>(
174         &self,
175         hcx: &mut StableHashingContext<'a>,
176         hasher: &mut StableHasher<W>,
177     ) {
178         let mir::interpret::Allocation {
179             bytes, relocations, undef_mask, align, mutability,
180             extra: _,
181         } = self;
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);
186         }
187         undef_mask.hash_stable(hcx, hasher);
188         align.hash_stable(hcx, hasher);
189         mutability.hash_stable(hcx, hasher);
190     }
191 }
192
193 impl_stable_hash_for!(enum ::syntax::ast::Mutability {
194     Immutable,
195     Mutable
196 });
197
198 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
199     type KeyType = region::Scope;
200
201     #[inline]
202     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
203         *self
204     }
205 }
206
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)
214     }
215 }
216
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)
224     }
225 }
226
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)
234     }
235 }
236
237 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
238 where
239     T: HashStable<StableHashingContext<'a>>,
240 {
241     fn hash_stable<W: StableHasherResult>(&self,
242                                           hcx: &mut StableHashingContext<'a>,
243                                           hasher: &mut StableHasher<W>) {
244         self.borrow().hash_stable(hcx, hasher);
245     }
246 }
247
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 {
255                 ref map
256             } = *self;
257
258             map.hash_stable(hcx, hasher);
259         });
260     }
261 }