]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/impls_ty.rs
Rollup merge of #68033 - ollie27:win_f32, r=dtolnay
[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, NodeIdHashingMode, StableHashingContext};
5 use crate::middle::region;
6 use crate::mir;
7 use crate::ty;
8 use rustc_data_structures::fx::FxHashMap;
9 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
10 use std::cell::RefCell;
11 use std::mem;
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>> for ty::RegionKind {
63     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
64         mem::discriminant(self).hash_stable(hcx, hasher);
65         match *self {
66             ty::ReErased | ty::ReStatic | ty::ReEmpty => {
67                 // No variant fields to hash for these ...
68             }
69             ty::ReLateBound(db, ty::BrAnon(i)) => {
70                 db.hash_stable(hcx, hasher);
71                 i.hash_stable(hcx, hasher);
72             }
73             ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
74                 db.hash_stable(hcx, hasher);
75                 def_id.hash_stable(hcx, hasher);
76                 name.hash_stable(hcx, hasher);
77             }
78             ty::ReLateBound(db, ty::BrEnv) => {
79                 db.hash_stable(hcx, hasher);
80             }
81             ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
82                 def_id.hash_stable(hcx, hasher);
83                 index.hash_stable(hcx, hasher);
84                 name.hash_stable(hcx, hasher);
85             }
86             ty::ReScope(scope) => {
87                 scope.hash_stable(hcx, hasher);
88             }
89             ty::ReFree(ref free_region) => {
90                 free_region.hash_stable(hcx, hasher);
91             }
92             ty::ReClosureBound(vid) => {
93                 vid.hash_stable(hcx, hasher);
94             }
95             ty::ReVar(..) | ty::RePlaceholder(..) => {
96                 bug!("StableHasher: unexpected region {:?}", *self)
97             }
98         }
99     }
100 }
101
102 impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
103     #[inline]
104     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
105         self.index().hash_stable(hcx, hasher);
106     }
107 }
108
109 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> {
110     #[inline]
111     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
112         self.index.hash_stable(hcx, hasher);
113     }
114 }
115
116 impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar {
117     #[inline]
118     fn hash_stable(&self, hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher) {
119         self.index().hash_stable(hcx, hasher);
120     }
121 }
122
123 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::Binder<T>
124 where
125     T: HashStable<StableHashingContext<'a>>,
126 {
127     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
128         self.skip_binder().hash_stable(hcx, hasher);
129     }
130 }
131
132 // AllocIds get resolved to whatever they point to (to be stable)
133 impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
134     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
135         ty::tls::with_opt(|tcx| {
136             trace!("hashing {:?}", *self);
137             let tcx = tcx.expect("can't hash AllocIds during hir lowering");
138             let alloc_kind = tcx.alloc_map.lock().get(*self);
139             alloc_kind.hash_stable(hcx, hasher);
140         });
141     }
142 }
143
144 // `Relocations` with default type parameters is a sorted map.
145 impl<'a, Tag> HashStable<StableHashingContext<'a>> for mir::interpret::Relocations<Tag>
146 where
147     Tag: HashStable<StableHashingContext<'a>>,
148 {
149     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
150         self.len().hash_stable(hcx, hasher);
151         for reloc in self.iter() {
152             reloc.hash_stable(hcx, hasher);
153         }
154     }
155 }
156
157 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
158     type KeyType = region::Scope;
159
160     #[inline]
161     fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
162         *self
163     }
164 }
165
166 impl<'a> HashStable<StableHashingContext<'a>> for ty::TyVid {
167     fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
168         // `TyVid` values are confined to an inference context and hence
169         // should not be hashed.
170         bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
171     }
172 }
173
174 impl<'a> HashStable<StableHashingContext<'a>> for ty::IntVid {
175     fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
176         // `IntVid` values are confined to an inference context and hence
177         // should not be hashed.
178         bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
179     }
180 }
181
182 impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
183     fn hash_stable(&self, _hcx: &mut StableHashingContext<'a>, _hasher: &mut StableHasher) {
184         // `FloatVid` values are confined to an inference context and hence
185         // should not be hashed.
186         bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
187     }
188 }
189
190 impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
191 where
192     T: HashStable<StableHashingContext<'a>>,
193 {
194     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
195         self.borrow().hash_stable(hcx, hasher);
196     }
197 }
198
199 impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::privacy::AccessLevels {
200     fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
201         hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
202             let crate::middle::privacy::AccessLevels { ref map } = *self;
203
204             map.hash_stable(hcx, hasher);
205         });
206     }
207 }