]>
Commit | Line | Data |
---|---|---|
cc61c64b XL |
1 | //! This module contains `HashStable` implementations for various data types |
2 | //! from rustc::ty in no particular order. | |
3 | ||
9fa01778 | 4 | use crate::ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; |
2c00a5a8 | 5 | use rustc_data_structures::fx::FxHashMap; |
e74abb32 | 6 | use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher}; |
2c00a5a8 | 7 | use std::cell::RefCell; |
cc61c64b | 8 | use std::mem; |
9fa01778 | 9 | use crate::middle::region; |
9fa01778 XL |
10 | use crate::ty; |
11 | use crate::mir; | |
cc61c64b | 12 | |
dc9dc135 XL |
13 | impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T> |
14 | where | |
15 | T: HashStable<StableHashingContext<'a>>, | |
16 | { | |
e74abb32 | 17 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
2c00a5a8 XL |
18 | thread_local! { |
19 | static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> = | |
0bf4aa26 | 20 | RefCell::new(Default::default()); |
2c00a5a8 XL |
21 | } |
22 | ||
23 | let hash = CACHE.with(|cache| { | |
24 | let key = (self.as_ptr() as usize, self.len()); | |
25 | if let Some(&hash) = cache.borrow().get(&key) { | |
26 | return hash; | |
27 | } | |
28 | ||
29 | let mut hasher = StableHasher::new(); | |
30 | (&self[..]).hash_stable(hcx, &mut hasher); | |
31 | ||
32 | let hash: Fingerprint = hasher.finish(); | |
33 | cache.borrow_mut().insert(key, hash); | |
34 | hash | |
35 | }); | |
36 | ||
37 | hash.hash_stable(hcx, hasher); | |
cc61c64b XL |
38 | } |
39 | } | |
40 | ||
dc9dc135 XL |
41 | impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T> |
42 | where | |
43 | T: HashStable<StableHashingContext<'a>>, | |
83c7162d XL |
44 | { |
45 | type KeyType = Fingerprint; | |
46 | ||
47 | #[inline] | |
48 | fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint { | |
49 | let mut hasher = StableHasher::new(); | |
50 | let mut hcx: StableHashingContext<'a> = hcx.clone(); | |
51 | self.hash_stable(&mut hcx, &mut hasher); | |
52 | hasher.finish() | |
53 | } | |
54 | } | |
55 | ||
e74abb32 XL |
56 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'tcx> { |
57 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { | |
0531ce1d XL |
58 | self.unpack().hash_stable(hcx, hasher); |
59 | } | |
60 | } | |
61 | ||
0531ce1d | 62 | impl<'a> HashStable<StableHashingContext<'a>> |
041b39d2 | 63 | for ty::RegionKind { |
e74abb32 | 64 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
cc61c64b XL |
65 | mem::discriminant(self).hash_stable(hcx, hasher); |
66 | match *self { | |
67 | ty::ReErased | | |
68 | ty::ReStatic | | |
69 | ty::ReEmpty => { | |
70 | // No variant fields to hash for these ... | |
71 | } | |
72 | ty::ReLateBound(db, ty::BrAnon(i)) => { | |
94b46f34 | 73 | db.hash_stable(hcx, hasher); |
cc61c64b XL |
74 | i.hash_stable(hcx, hasher); |
75 | } | |
3b2f2976 | 76 | ty::ReLateBound(db, ty::BrNamed(def_id, name)) => { |
94b46f34 | 77 | db.hash_stable(hcx, hasher); |
3b2f2976 XL |
78 | def_id.hash_stable(hcx, hasher); |
79 | name.hash_stable(hcx, hasher); | |
80 | } | |
ea8adc8c | 81 | ty::ReLateBound(db, ty::BrEnv) => { |
94b46f34 | 82 | db.hash_stable(hcx, hasher); |
ea8adc8c | 83 | } |
7cac9316 XL |
84 | ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => { |
85 | def_id.hash_stable(hcx, hasher); | |
cc61c64b XL |
86 | index.hash_stable(hcx, hasher); |
87 | name.hash_stable(hcx, hasher); | |
88 | } | |
ea8adc8c XL |
89 | ty::ReScope(scope) => { |
90 | scope.hash_stable(hcx, hasher); | |
cc61c64b XL |
91 | } |
92 | ty::ReFree(ref free_region) => { | |
93 | free_region.hash_stable(hcx, hasher); | |
94 | } | |
ff7c6d11 XL |
95 | ty::ReClosureBound(vid) => { |
96 | vid.hash_stable(hcx, hasher); | |
97 | } | |
cc61c64b | 98 | ty::ReVar(..) | |
0bf4aa26 | 99 | ty::RePlaceholder(..) => { |
94b46f34 | 100 | bug!("StableHasher: unexpected region {:?}", *self) |
cc61c64b XL |
101 | } |
102 | } | |
103 | } | |
104 | } | |
105 | ||
0531ce1d XL |
106 | impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid { |
107 | #[inline] | |
e74abb32 | 108 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
0531ce1d XL |
109 | self.index().hash_stable(hcx, hasher); |
110 | } | |
111 | } | |
112 | ||
dc9dc135 | 113 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> { |
ff7c6d11 | 114 | #[inline] |
e74abb32 | 115 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
532ac7d7 | 116 | self.index.hash_stable(hcx, hasher); |
cc61c64b XL |
117 | } |
118 | } | |
119 | ||
dc9dc135 | 120 | impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar { |
532ac7d7 | 121 | #[inline] |
e74abb32 | 122 | fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { |
532ac7d7 | 123 | self.index().hash_stable(hcx, hasher); |
2c00a5a8 XL |
124 | } |
125 | } | |
126 | ||
dc9dc135 XL |
127 | impl<'a, T> HashStable<StableHashingContext<'a>> for ty::Binder<T> |
128 | where | |
129 | T: HashStable<StableHashingContext<'a>>, | |
cc61c64b | 130 | { |
e74abb32 | 131 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
83c7162d | 132 | self.skip_binder().hash_stable(hcx, hasher); |
cc61c64b XL |
133 | } |
134 | } | |
135 | ||
a1dfa0c6 | 136 | // AllocIds get resolved to whatever they point to (to be stable) |
0531ce1d | 137 | impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId { |
e74abb32 | 138 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
0531ce1d XL |
139 | ty::tls::with_opt(|tcx| { |
140 | trace!("hashing {:?}", *self); | |
141 | let tcx = tcx.expect("can't hash AllocIds during hir lowering"); | |
b7449926 | 142 | let alloc_kind = tcx.alloc_map.lock().get(*self); |
94b46f34 | 143 | alloc_kind.hash_stable(hcx, hasher); |
0531ce1d XL |
144 | }); |
145 | } | |
146 | } | |
147 | ||
e1599b0c XL |
148 | // `Relocations` with default type parameters is a sorted map. |
149 | impl<'a, Tag> HashStable<StableHashingContext<'a>> | |
150 | for mir::interpret::Relocations<Tag> | |
151 | where | |
152 | Tag: HashStable<StableHashingContext<'a>>, | |
153 | { | |
e74abb32 | 154 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
e1599b0c XL |
155 | self.len().hash_stable(hcx, hasher); |
156 | for reloc in self.iter() { | |
0531ce1d | 157 | reloc.hash_stable(hcx, hasher); |
ea8adc8c XL |
158 | } |
159 | } | |
160 | } | |
161 | ||
0531ce1d | 162 | impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope { |
ea8adc8c XL |
163 | type KeyType = region::Scope; |
164 | ||
165 | #[inline] | |
0531ce1d | 166 | fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope { |
ea8adc8c | 167 | *self |
cc61c64b XL |
168 | } |
169 | } | |
170 | ||
dc9dc135 | 171 | impl<'a> HashStable<StableHashingContext<'a>> for ty::TyVid { |
e74abb32 | 172 | fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) { |
e1599b0c | 173 | // `TyVid` values are confined to an inference context and hence |
0531ce1d | 174 | // should not be hashed. |
b7449926 | 175 | bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self) |
0531ce1d XL |
176 | } |
177 | } | |
178 | ||
dc9dc135 | 179 | impl<'a> HashStable<StableHashingContext<'a>> for ty::IntVid { |
e74abb32 | 180 | fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) { |
e1599b0c | 181 | // `IntVid` values are confined to an inference context and hence |
0531ce1d | 182 | // should not be hashed. |
b7449926 | 183 | bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self) |
0531ce1d XL |
184 | } |
185 | } | |
186 | ||
dc9dc135 | 187 | impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid { |
e74abb32 | 188 | fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) { |
e1599b0c | 189 | // `FloatVid` values are confined to an inference context and hence |
0531ce1d | 190 | // should not be hashed. |
b7449926 | 191 | bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self) |
0531ce1d XL |
192 | } |
193 | } | |
194 | ||
dc9dc135 XL |
195 | impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T> |
196 | where | |
197 | T: HashStable<StableHashingContext<'a>>, | |
ea8adc8c | 198 | { |
e74abb32 | 199 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
ea8adc8c XL |
200 | self.borrow().hash_stable(hcx, hasher); |
201 | } | |
202 | } | |
203 | ||
0531ce1d | 204 | impl<'a> HashStable<StableHashingContext<'a>> |
9fa01778 | 205 | for crate::middle::privacy::AccessLevels { |
e74abb32 | 206 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
ea8adc8c | 207 | hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { |
9fa01778 | 208 | let crate::middle::privacy::AccessLevels { |
ea8adc8c XL |
209 | ref map |
210 | } = *self; | |
211 | ||
212 | map.hash_stable(hcx, hasher); | |
213 | }); | |
214 | } | |
215 | } |