]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_ty.rs
Auto merge of #58953 - jethrogb:jb/unify-ffi, r=alexcrichton
[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, 'gcx, T> HashStable<StableHashingContext<'a>>
15 for &'gcx ty::List<T>
16     where T: HashStable<StableHashingContext<'a>> {
17     fn hash_stable<W: StableHasherResult>(&self,
18                                           hcx: &mut StableHashingContext<'a>,
19                                           hasher: &mut StableHasher<W>) {
20         thread_local! {
21             static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
22                 RefCell::new(Default::default());
23         }
24
25         let hash = CACHE.with(|cache| {
26             let key = (self.as_ptr() as usize, self.len());
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, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::List<T>
44     where T: HashStable<StableHashingContext<'a>>
45 {
46     type KeyType = Fingerprint;
47
48     #[inline]
49     fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
50         let mut hasher = StableHasher::new();
51         let mut hcx: StableHashingContext<'a> = hcx.clone();
52         self.hash_stable(&mut hcx, &mut hasher);
53         hasher.finish()
54     }
55 }
56
57 impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
58     fn hash_stable<W: StableHasherResult>(&self,
59                                           hcx: &mut StableHashingContext<'a>,
60                                           hasher: &mut StableHasher<W>) {
61         self.unpack().hash_stable(hcx, hasher);
62     }
63 }
64
65 impl<'a> HashStable<StableHashingContext<'a>>
66 for ty::RegionKind {
67     fn hash_stable<W: StableHasherResult>(&self,
68                                           hcx: &mut StableHashingContext<'a>,
69                                           hasher: &mut StableHasher<W>) {
70         mem::discriminant(self).hash_stable(hcx, hasher);
71         match *self {
72             ty::ReErased |
73             ty::ReStatic |
74             ty::ReEmpty => {
75                 // No variant fields to hash for these ...
76             }
77             ty::ReLateBound(db, ty::BrAnon(i)) => {
78                 db.hash_stable(hcx, hasher);
79                 i.hash_stable(hcx, hasher);
80             }
81             ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
82                 db.hash_stable(hcx, hasher);
83                 def_id.hash_stable(hcx, hasher);
84                 name.hash_stable(hcx, hasher);
85             }
86             ty::ReLateBound(db, ty::BrEnv) => {
87                 db.hash_stable(hcx, hasher);
88             }
89             ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
90                 def_id.hash_stable(hcx, hasher);
91                 index.hash_stable(hcx, hasher);
92                 name.hash_stable(hcx, hasher);
93             }
94             ty::ReScope(scope) => {
95                 scope.hash_stable(hcx, hasher);
96             }
97             ty::ReFree(ref free_region) => {
98                 free_region.hash_stable(hcx, hasher);
99             }
100             ty::ReClosureBound(vid) => {
101                 vid.hash_stable(hcx, hasher);
102             }
103             ty::ReLateBound(..) |
104             ty::ReVar(..) |
105             ty::RePlaceholder(..) => {
106                 bug!("StableHasher: unexpected region {:?}", *self)
107             }
108         }
109     }
110 }
111
112 impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
113     #[inline]
114     fn hash_stable<W: StableHasherResult>(&self,
115                                           hcx: &mut StableHashingContext<'a>,
116                                           hasher: &mut StableHasher<W>) {
117         self.index().hash_stable(hcx, hasher);
118     }
119 }
120
121 impl<'gcx, 'tcx> HashStable<StableHashingContext<'gcx>> for ty::ConstVid<'tcx> {
122     #[inline]
123     fn hash_stable<W: StableHasherResult>(&self,
124                                           hcx: &mut StableHashingContext<'gcx>,
125                                           hasher: &mut StableHasher<W>) {
126         self.index.hash_stable(hcx, hasher);
127     }
128 }
129
130 impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundVar {
131     #[inline]
132     fn hash_stable<W: StableHasherResult>(&self,
133                                           hcx: &mut StableHashingContext<'gcx>,
134                                           hasher: &mut StableHasher<W>) {
135         self.index().hash_stable(hcx, hasher);
136     }
137 }
138
139 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
140     where T: HashStable<StableHashingContext<'a>>
141 {
142     fn hash_stable<W: StableHasherResult>(&self,
143                                           hcx: &mut StableHashingContext<'a>,
144                                           hasher: &mut StableHasher<W>) {
145         self.skip_binder().hash_stable(hcx, hasher);
146     }
147 }
148
149 // AllocIds get resolved to whatever they point to (to be stable)
150 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
151     fn hash_stable<W: StableHasherResult>(
152         &self,
153         hcx: &mut StableHashingContext<'a>,
154         hasher: &mut StableHasher<W>,
155     ) {
156         ty::tls::with_opt(|tcx| {
157             trace!("hashing {:?}", *self);
158             let tcx = tcx.expect("can't hash AllocIds during hir lowering");
159             let alloc_kind = tcx.alloc_map.lock().get(*self);
160             alloc_kind.hash_stable(hcx, hasher);
161         });
162     }
163 }
164
165 // Allocations treat their relocations specially
166 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
167     fn hash_stable<W: StableHasherResult>(
168         &self,
169         hcx: &mut StableHashingContext<'a>,
170         hasher: &mut StableHasher<W>,
171     ) {
172         self.bytes.hash_stable(hcx, hasher);
173         for reloc in self.relocations.iter() {
174             reloc.hash_stable(hcx, hasher);
175         }
176         self.undef_mask.hash_stable(hcx, hasher);
177         self.align.hash_stable(hcx, hasher);
178         self.mutability.hash_stable(hcx, hasher);
179     }
180 }
181
182 impl_stable_hash_for!(enum ::syntax::ast::Mutability {
183     Immutable,
184     Mutable
185 });
186
187 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
188     type KeyType = region::Scope;
189
190     #[inline]
191     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
192         *self
193     }
194 }
195
196 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
197 for ty::TyVid
198 {
199     fn hash_stable<W: StableHasherResult>(&self,
200                                           _hcx: &mut StableHashingContext<'a>,
201                                           _hasher: &mut StableHasher<W>) {
202         // TyVid values are confined to an inference context and hence
203         // should not be hashed.
204         bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
205     }
206 }
207
208 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
209 for ty::IntVid
210 {
211     fn hash_stable<W: StableHasherResult>(&self,
212                                           _hcx: &mut StableHashingContext<'a>,
213                                           _hasher: &mut StableHasher<W>) {
214         // IntVid values are confined to an inference context and hence
215         // should not be hashed.
216         bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
217     }
218 }
219
220 impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
221 for ty::FloatVid
222 {
223     fn hash_stable<W: StableHasherResult>(&self,
224                                           _hcx: &mut StableHashingContext<'a>,
225                                           _hasher: &mut StableHasher<W>) {
226         // FloatVid values are confined to an inference context and hence
227         // should not be hashed.
228         bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
229     }
230 }
231
232 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
233 for ty::steal::Steal<T>
234     where T: HashStable<StableHashingContext<'a>>
235 {
236     fn hash_stable<W: StableHasherResult>(&self,
237                                           hcx: &mut StableHashingContext<'a>,
238                                           hasher: &mut StableHasher<W>) {
239         self.borrow().hash_stable(hcx, hasher);
240     }
241 }
242
243 impl<'a> HashStable<StableHashingContext<'a>>
244 for crate::middle::privacy::AccessLevels {
245     fn hash_stable<W: StableHasherResult>(&self,
246                                           hcx: &mut StableHashingContext<'a>,
247                                           hasher: &mut StableHasher<W>) {
248         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
249             let crate::middle::privacy::AccessLevels {
250                 ref map
251             } = *self;
252
253             map.hash_stable(hcx, hasher);
254         });
255     }
256 }