]>
Commit | Line | Data |
---|---|---|
cc61c64b | 1 | //! This module contains `HashStable` implementations for various data types |
ba9703b0 | 2 | //! from `rustc_middle::ty` in no particular order. |
cc61c64b | 3 | |
dfeec247 XL |
4 | use crate::middle::region; |
5 | use crate::mir; | |
6 | use crate::ty; | |
ba9703b0 | 7 | use rustc_data_structures::fingerprint::Fingerprint; |
2c00a5a8 | 8 | use rustc_data_structures::fx::FxHashMap; |
5099ac24 | 9 | use rustc_data_structures::stable_hasher::HashingControls; |
dfeec247 | 10 | use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; |
c295e0f8 | 11 | use rustc_query_system::ich::StableHashingContext; |
2c00a5a8 | 12 | use std::cell::RefCell; |
cc61c64b | 13 | use std::mem; |
cc61c64b | 14 | |
dc9dc135 XL |
15 | impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T> |
16 | where | |
17 | T: HashStable<StableHashingContext<'a>>, | |
18 | { | |
e74abb32 | 19 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
2c00a5a8 | 20 | thread_local! { |
5099ac24 | 21 | static CACHE: RefCell<FxHashMap<(usize, usize, HashingControls), Fingerprint>> = |
0bf4aa26 | 22 | RefCell::new(Default::default()); |
2c00a5a8 XL |
23 | } |
24 | ||
25 | let hash = CACHE.with(|cache| { | |
5099ac24 | 26 | let key = (self.as_ptr() as usize, self.len(), hcx.hashing_controls()); |
2c00a5a8 XL |
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); | |
cc61c64b XL |
40 | } |
41 | } | |
42 | ||
dc9dc135 XL |
43 | impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T> |
44 | where | |
45 | T: HashStable<StableHashingContext<'a>>, | |
83c7162d XL |
46 | { |
47 | type KeyType = Fingerprint; | |
48 | ||
49 | #[inline] | |
50 | 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 | ||
e74abb32 XL |
58 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'tcx> { |
59 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { | |
0531ce1d XL |
60 | self.unpack().hash_stable(hcx, hasher); |
61 | } | |
62 | } | |
63 | ||
dfeec247 | 64 | impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionKind { |
e74abb32 | 65 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
cc61c64b XL |
66 | mem::discriminant(self).hash_stable(hcx, hasher); |
67 | match *self { | |
74b04a01 | 68 | ty::ReErased | ty::ReStatic => { |
cc61c64b XL |
69 | // No variant fields to hash for these ... |
70 | } | |
74b04a01 XL |
71 | ty::ReEmpty(universe) => { |
72 | universe.hash_stable(hcx, hasher); | |
73 | } | |
cdc7bbd5 | 74 | ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrAnon(i), .. }) => { |
94b46f34 | 75 | db.hash_stable(hcx, hasher); |
cc61c64b XL |
76 | i.hash_stable(hcx, hasher); |
77 | } | |
cdc7bbd5 | 78 | ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrNamed(def_id, name), .. }) => { |
94b46f34 | 79 | db.hash_stable(hcx, hasher); |
3b2f2976 XL |
80 | def_id.hash_stable(hcx, hasher); |
81 | name.hash_stable(hcx, hasher); | |
82 | } | |
cdc7bbd5 | 83 | ty::ReLateBound(db, ty::BoundRegion { kind: ty::BrEnv, .. }) => { |
94b46f34 | 84 | db.hash_stable(hcx, hasher); |
ea8adc8c | 85 | } |
7cac9316 XL |
86 | ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => { |
87 | def_id.hash_stable(hcx, hasher); | |
cc61c64b XL |
88 | index.hash_stable(hcx, hasher); |
89 | name.hash_stable(hcx, hasher); | |
90 | } | |
cc61c64b XL |
91 | ty::ReFree(ref free_region) => { |
92 | free_region.hash_stable(hcx, hasher); | |
93 | } | |
c295e0f8 XL |
94 | ty::RePlaceholder(p) => { |
95 | p.hash_stable(hcx, hasher); | |
96 | } | |
97 | ty::ReVar(..) => { | |
94b46f34 | 98 | bug!("StableHasher: unexpected region {:?}", *self) |
cc61c64b XL |
99 | } |
100 | } | |
101 | } | |
102 | } | |
103 | ||
0531ce1d XL |
104 | impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid { |
105 | #[inline] | |
e74abb32 | 106 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
0531ce1d XL |
107 | self.index().hash_stable(hcx, hasher); |
108 | } | |
109 | } | |
110 | ||
dc9dc135 | 111 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> { |
ff7c6d11 | 112 | #[inline] |
e74abb32 | 113 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
532ac7d7 | 114 | self.index.hash_stable(hcx, hasher); |
cc61c64b XL |
115 | } |
116 | } | |
117 | ||
dc9dc135 | 118 | impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar { |
532ac7d7 | 119 | #[inline] |
e74abb32 | 120 | fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) { |
532ac7d7 | 121 | self.index().hash_stable(hcx, hasher); |
2c00a5a8 XL |
122 | } |
123 | } | |
124 | ||
cdc7bbd5 | 125 | impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ty::Binder<'tcx, T> |
dc9dc135 XL |
126 | where |
127 | T: HashStable<StableHashingContext<'a>>, | |
cc61c64b | 128 | { |
e74abb32 | 129 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
f035d41b | 130 | self.as_ref().skip_binder().hash_stable(hcx, hasher); |
cdc7bbd5 | 131 | self.bound_vars().hash_stable(hcx, hasher); |
cc61c64b XL |
132 | } |
133 | } | |
134 | ||
a1dfa0c6 | 135 | // AllocIds get resolved to whatever they point to (to be stable) |
0531ce1d | 136 | impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId { |
e74abb32 | 137 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
0531ce1d XL |
138 | ty::tls::with_opt(|tcx| { |
139 | trace!("hashing {:?}", *self); | |
140 | let tcx = tcx.expect("can't hash AllocIds during hir lowering"); | |
f9f354fc | 141 | tcx.get_global_alloc(*self).hash_stable(hcx, hasher); |
0531ce1d XL |
142 | }); |
143 | } | |
144 | } | |
145 | ||
e1599b0c | 146 | // `Relocations` with default type parameters is a sorted map. |
dfeec247 | 147 | impl<'a, Tag> HashStable<StableHashingContext<'a>> for mir::interpret::Relocations<Tag> |
e1599b0c XL |
148 | where |
149 | Tag: HashStable<StableHashingContext<'a>>, | |
150 | { | |
e74abb32 | 151 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
e1599b0c XL |
152 | self.len().hash_stable(hcx, hasher); |
153 | for reloc in self.iter() { | |
0531ce1d | 154 | reloc.hash_stable(hcx, hasher); |
ea8adc8c XL |
155 | } |
156 | } | |
157 | } | |
158 | ||
0531ce1d | 159 | impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope { |
ea8adc8c XL |
160 | type KeyType = region::Scope; |
161 | ||
162 | #[inline] | |
0531ce1d | 163 | fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope { |
ea8adc8c | 164 | *self |
cc61c64b XL |
165 | } |
166 | } |