1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! This module contains `HashStable` implementations for various data types
12 //! from rustc::ty in no particular order.
14 use ich::StableHashingContext;
15 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
17 use std::hash as std_hash;
22 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Ty<'tcx> {
23 fn hash_stable<W: StableHasherResult>(&self,
24 hcx: &mut StableHashingContext<'a, 'tcx>,
25 hasher: &mut StableHasher<W>) {
26 let type_hash = hcx.tcx().type_id_hash(*self);
27 type_hash.hash_stable(hcx, hasher);
31 impl_stable_hash_for!(struct ty::ItemSubsts<'tcx> { substs });
33 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for ty::Slice<T>
34 where T: HashStable<StableHashingContext<'a, 'tcx>> {
35 fn hash_stable<W: StableHasherResult>(&self,
36 hcx: &mut StableHashingContext<'a, 'tcx>,
37 hasher: &mut StableHasher<W>) {
38 (&**self).hash_stable(hcx, hasher);
42 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::subst::Kind<'tcx> {
43 fn hash_stable<W: StableHasherResult>(&self,
44 hcx: &mut StableHashingContext<'a, 'tcx>,
45 hasher: &mut StableHasher<W>) {
46 self.as_type().hash_stable(hcx, hasher);
47 self.as_region().hash_stable(hcx, hasher);
51 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Region {
52 fn hash_stable<W: StableHasherResult>(&self,
53 hcx: &mut StableHashingContext<'a, 'tcx>,
54 hasher: &mut StableHasher<W>) {
55 mem::discriminant(self).hash_stable(hcx, hasher);
60 // No variant fields to hash for these ...
62 ty::ReLateBound(db, ty::BrAnon(i)) => {
63 db.depth.hash_stable(hcx, hasher);
64 i.hash_stable(hcx, hasher);
66 ty::ReEarlyBound(ty::EarlyBoundRegion { index, name }) => {
67 index.hash_stable(hcx, hasher);
68 name.hash_stable(hcx, hasher);
74 ty::ReSkolemized(..) => {
75 bug!("TypeIdHasher: unexpected region {:?}", *self)
81 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::AutoBorrow<'tcx> {
82 fn hash_stable<W: StableHasherResult>(&self,
83 hcx: &mut StableHashingContext<'a, 'tcx>,
84 hasher: &mut StableHasher<W>) {
85 mem::discriminant(self).hash_stable(hcx, hasher);
87 ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
88 region.hash_stable(hcx, hasher);
89 mutability.hash_stable(hcx, hasher);
91 ty::adjustment::AutoBorrow::RawPtr(mutability) => {
92 mutability.hash_stable(hcx, hasher);
98 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::Adjust<'tcx> {
99 fn hash_stable<W: StableHasherResult>(&self,
100 hcx: &mut StableHashingContext<'a, 'tcx>,
101 hasher: &mut StableHasher<W>) {
102 mem::discriminant(self).hash_stable(hcx, hasher);
104 ty::adjustment::Adjust::NeverToAny |
105 ty::adjustment::Adjust::ReifyFnPointer |
106 ty::adjustment::Adjust::UnsafeFnPointer |
107 ty::adjustment::Adjust::ClosureFnPointer |
108 ty::adjustment::Adjust::MutToConstPointer => {}
109 ty::adjustment::Adjust::DerefRef { autoderefs, ref autoref, unsize } => {
110 autoderefs.hash_stable(hcx, hasher);
111 autoref.hash_stable(hcx, hasher);
112 unsize.hash_stable(hcx, hasher);
118 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
119 impl_stable_hash_for!(struct ty::MethodCall { expr_id, autoderef });
120 impl_stable_hash_for!(struct ty::MethodCallee<'tcx> { def_id, ty, substs });
121 impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
122 impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
124 impl_stable_hash_for!(enum ty::BorrowKind {
131 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::UpvarCapture<'tcx> {
132 fn hash_stable<W: StableHasherResult>(&self,
133 hcx: &mut StableHashingContext<'a, 'tcx>,
134 hasher: &mut StableHasher<W>) {
135 mem::discriminant(self).hash_stable(hcx, hasher);
137 ty::UpvarCapture::ByValue => {}
138 ty::UpvarCapture::ByRef(ref up_var_borrow) => {
139 up_var_borrow.hash_stable(hcx, hasher);
145 impl_stable_hash_for!(struct ty::FnSig<'tcx> {
152 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for ty::Binder<T>
153 where T: HashStable<StableHashingContext<'a, 'tcx>> + ty::fold::TypeFoldable<'tcx>
155 fn hash_stable<W: StableHasherResult>(&self,
156 hcx: &mut StableHashingContext<'a, 'tcx>,
157 hasher: &mut StableHasher<W>) {
158 hcx.tcx().anonymize_late_bound_regions(self).0.hash_stable(hcx, hasher);
162 impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
164 impl_stable_hash_for!(enum ty::Visibility {
170 impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
171 impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
172 impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 });
174 impl<'a, 'tcx, A, B> HashStable<StableHashingContext<'a, 'tcx>> for ty::OutlivesPredicate<A, B>
175 where A: HashStable<StableHashingContext<'a, 'tcx>>,
176 B: HashStable<StableHashingContext<'a, 'tcx>>,
178 fn hash_stable<W: StableHasherResult>(&self,
179 hcx: &mut StableHashingContext<'a, 'tcx>,
180 hasher: &mut StableHasher<W>) {
181 let ty::OutlivesPredicate(ref a, ref b) = *self;
182 a.hash_stable(hcx, hasher);
183 b.hash_stable(hcx, hasher);
187 impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
188 impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_name });
191 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Predicate<'tcx> {
192 fn hash_stable<W: StableHasherResult>(&self,
193 hcx: &mut StableHashingContext<'a, 'tcx>,
194 hasher: &mut StableHasher<W>) {
195 mem::discriminant(self).hash_stable(hcx, hasher);
197 ty::Predicate::Trait(ref pred) => {
198 pred.hash_stable(hcx, hasher);
200 ty::Predicate::Equate(ref pred) => {
201 pred.hash_stable(hcx, hasher);
203 ty::Predicate::RegionOutlives(ref pred) => {
204 pred.hash_stable(hcx, hasher);
206 ty::Predicate::TypeOutlives(ref pred) => {
207 pred.hash_stable(hcx, hasher);
209 ty::Predicate::Projection(ref pred) => {
210 pred.hash_stable(hcx, hasher);
212 ty::Predicate::WellFormed(ty) => {
213 ty.hash_stable(hcx, hasher);
215 ty::Predicate::ObjectSafe(def_id) => {
216 def_id.hash_stable(hcx, hasher);
218 ty::Predicate::ClosureKind(def_id, closure_kind) => {
219 def_id.hash_stable(hcx, hasher);
220 closure_kind.hash_stable(hcx, hasher);
227 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::AdtFlags {
228 fn hash_stable<W: StableHasherResult>(&self,
229 _: &mut StableHashingContext<'a, 'tcx>,
230 hasher: &mut StableHasher<W>) {
231 std_hash::Hash::hash(self, hasher);
235 impl_stable_hash_for!(struct ty::VariantDef {
243 impl_stable_hash_for!(enum ty::VariantDiscr {
248 impl_stable_hash_for!(struct ty::FieldDef {
254 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>>
255 for ::middle::const_val::ConstVal<'tcx> {
256 fn hash_stable<W: StableHasherResult>(&self,
257 hcx: &mut StableHashingContext<'a, 'tcx>,
258 hasher: &mut StableHasher<W>) {
259 use middle::const_val::ConstVal;
261 mem::discriminant(self).hash_stable(hcx, hasher);
264 ConstVal::Float(ref value) => {
265 value.hash_stable(hcx, hasher);
267 ConstVal::Integral(ref value) => {
268 value.hash_stable(hcx, hasher);
270 ConstVal::Str(ref value) => {
271 value.hash_stable(hcx, hasher);
273 ConstVal::ByteStr(ref value) => {
274 value.hash_stable(hcx, hasher);
276 ConstVal::Bool(value) => {
277 value.hash_stable(hcx, hasher);
279 ConstVal::Function(def_id, substs) => {
280 def_id.hash_stable(hcx, hasher);
281 substs.hash_stable(hcx, hasher);
283 ConstVal::Struct(ref _name_value_map) => {
284 // BTreeMap<ast::Name, ConstVal<'tcx>>),
285 panic!("Ordering still unstable")
287 ConstVal::Tuple(ref value) => {
288 value.hash_stable(hcx, hasher);
290 ConstVal::Array(ref value) => {
291 value.hash_stable(hcx, hasher);
293 ConstVal::Repeat(ref value, times) => {
294 value.hash_stable(hcx, hasher);
295 times.hash_stable(hcx, hasher);
297 ConstVal::Char(value) => {
298 value.hash_stable(hcx, hasher);
304 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
307 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
312 impl_stable_hash_for!(enum ty::Variance {
319 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
323 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Generics {
324 fn hash_stable<W: StableHasherResult>(&self,
325 hcx: &mut StableHashingContext<'a, 'tcx>,
326 hasher: &mut StableHasher<W>) {
334 // Reverse map to each `TypeParameterDef`'s `index` field, from
335 // `def_id.index` (`def_id.krate` is the same as the item's).
336 type_param_to_index: _, // Don't hash this
340 parent.hash_stable(hcx, hasher);
341 parent_regions.hash_stable(hcx, hasher);
342 parent_types.hash_stable(hcx, hasher);
343 regions.hash_stable(hcx, hasher);
344 types.hash_stable(hcx, hasher);
345 has_self.hash_stable(hcx, hasher);
349 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionParameterDef {
350 fn hash_stable<W: StableHasherResult>(&self,
351 hcx: &mut StableHashingContext<'a, 'tcx>,
352 hasher: &mut StableHasher<W>) {
353 let ty::RegionParameterDef {
361 name.hash_stable(hcx, hasher);
362 def_id.hash_stable(hcx, hasher);
363 index.hash_stable(hcx, hasher);
364 pure_wrt_drop.hash_stable(hcx, hasher);
368 impl_stable_hash_for!(struct ty::TypeParameterDef {
373 object_lifetime_default,
378 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>>
379 for ::middle::resolve_lifetime::Set1<T>
380 where T: HashStable<StableHashingContext<'a, 'tcx>>
382 fn hash_stable<W: StableHasherResult>(&self,
383 hcx: &mut StableHashingContext<'a, 'tcx>,
384 hasher: &mut StableHasher<W>) {
385 use middle::resolve_lifetime::Set1;
387 mem::discriminant(self).hash_stable(hcx, hasher);
393 Set1::One(ref value) => {
394 value.hash_stable(hcx, hasher);
400 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
402 EarlyBound(index, decl),
403 LateBound(db_index, decl),
404 LateBoundAnon(db_index, anon_index),
405 Free(call_site_scope_data, decl)
408 impl_stable_hash_for!(struct ::middle::region::CallSiteScopeData {
413 impl_stable_hash_for!(struct ty::DebruijnIndex {