]> git.proxmox.com Git - rustc.git/blob - src/librustc/ich/impls_ty.rs
New upstream version 1.41.1+dfsg1
[rustc.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, StableHasher};
7 use std::cell::RefCell;
8 use std::mem;
9 use crate::middle::region;
10 use crate::ty;
11 use crate::mir;
12
13 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for &'tcx ty::List<T>
14 where
15 T: HashStable<StableHashingContext<'a>>,
16 {
17 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
18 thread_local! {
19 static CACHE: RefCell<FxHashMap<(usize, usize), Fingerprint>> =
20 RefCell::new(Default::default());
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);
38 }
39 }
40
41 impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T>
42 where
43 T: HashStable<StableHashingContext<'a>>,
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
56 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'tcx> {
57 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
58 self.unpack().hash_stable(hcx, hasher);
59 }
60 }
61
62 impl<'a> HashStable<StableHashingContext<'a>>
63 for ty::RegionKind {
64 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
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)) => {
73 db.hash_stable(hcx, hasher);
74 i.hash_stable(hcx, hasher);
75 }
76 ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
77 db.hash_stable(hcx, hasher);
78 def_id.hash_stable(hcx, hasher);
79 name.hash_stable(hcx, hasher);
80 }
81 ty::ReLateBound(db, ty::BrEnv) => {
82 db.hash_stable(hcx, hasher);
83 }
84 ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
85 def_id.hash_stable(hcx, hasher);
86 index.hash_stable(hcx, hasher);
87 name.hash_stable(hcx, hasher);
88 }
89 ty::ReScope(scope) => {
90 scope.hash_stable(hcx, hasher);
91 }
92 ty::ReFree(ref free_region) => {
93 free_region.hash_stable(hcx, hasher);
94 }
95 ty::ReClosureBound(vid) => {
96 vid.hash_stable(hcx, hasher);
97 }
98 ty::ReVar(..) |
99 ty::RePlaceholder(..) => {
100 bug!("StableHasher: unexpected region {:?}", *self)
101 }
102 }
103 }
104 }
105
106 impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
107 #[inline]
108 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
109 self.index().hash_stable(hcx, hasher);
110 }
111 }
112
113 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> {
114 #[inline]
115 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
116 self.index.hash_stable(hcx, hasher);
117 }
118 }
119
120 impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar {
121 #[inline]
122 fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
123 self.index().hash_stable(hcx, hasher);
124 }
125 }
126
127 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
128 where
129 T: HashStable<StableHashingContext<'a>>,
130 {
131 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
132 self.skip_binder().hash_stable(hcx, hasher);
133 }
134 }
135
136 // AllocIds get resolved to whatever they point to (to be stable)
137 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
138 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
139 ty::tls::with_opt(|tcx| {
140 trace!("hashing {:?}", *self);
141 let tcx = tcx.expect("can't hash AllocIds during hir lowering");
142 let alloc_kind = tcx.alloc_map.lock().get(*self);
143 alloc_kind.hash_stable(hcx, hasher);
144 });
145 }
146 }
147
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 {
154 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
155 self.len().hash_stable(hcx, hasher);
156 for reloc in self.iter() {
157 reloc.hash_stable(hcx, hasher);
158 }
159 }
160 }
161
162 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
163 type KeyType = region::Scope;
164
165 #[inline]
166 fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
167 *self
168 }
169 }
170
171 impl<'a> HashStable<StableHashingContext<'a>> for ty::TyVid {
172 fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
173 // `TyVid` values are confined to an inference context and hence
174 // should not be hashed.
175 bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
176 }
177 }
178
179 impl<'a> HashStable<StableHashingContext<'a>> for ty::IntVid {
180 fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
181 // `IntVid` values are confined to an inference context and hence
182 // should not be hashed.
183 bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
184 }
185 }
186
187 impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
188 fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
189 // `FloatVid` values are confined to an inference context and hence
190 // should not be hashed.
191 bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
192 }
193 }
194
195 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
196 where
197 T: HashStable<StableHashingContext<'a>>,
198 {
199 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
200 self.borrow().hash_stable(hcx, hasher);
201 }
202 }
203
204 impl<'a> HashStable<StableHashingContext<'a>>
205 for crate::middle::privacy::AccessLevels {
206 fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
207 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
208 let crate::middle::privacy::AccessLevels {
209 ref map
210 } = *self;
211
212 map.hash_stable(hcx, hasher);
213 });
214 }
215 }