]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_ty.rs
Rollup merge of #64603 - gilescope:unused-lifetime-warning, r=matthewjasper
[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, 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_stable_hash_for!(enum ::syntax::ast::Mutability {
163     Immutable,
164     Mutable
165 });
166
167 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
168     type KeyType = region::Scope;
169
170     #[inline]
171     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
172         *self
173     }
174 }
175
176 impl<'a> HashStable<StableHashingContext<'a>> for ty::TyVid {
177     fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
178         // `TyVid` values are confined to an inference context and hence
179         // should not be hashed.
180         bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
181     }
182 }
183
184 impl<'a> HashStable<StableHashingContext<'a>> for ty::IntVid {
185     fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
186         // `IntVid` values are confined to an inference context and hence
187         // should not be hashed.
188         bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
189     }
190 }
191
192 impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
193     fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
194         // `FloatVid` values are confined to an inference context and hence
195         // should not be hashed.
196         bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
197     }
198 }
199
200 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
201 where
202     T: HashStable<StableHashingContext<'a>>,
203 {
204     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
205         self.borrow().hash_stable(hcx, hasher);
206     }
207 }
208
209 impl<'a> HashStable<StableHashingContext<'a>>
210 for crate::middle::privacy::AccessLevels {
211     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
212         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
213             let crate::middle::privacy::AccessLevels {
214                 ref map
215             } = *self;
216
217             map.hash_stable(hcx, hasher);
218         });
219     }
220 }