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::{self, StableHashingContext, NodeIdHashingMode};
15 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
17 use std::hash as std_hash;
19 use syntax_pos::symbol::InternedString;
22 impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
23 for &'gcx ty::Slice<T>
24 where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> {
25 fn hash_stable<W: StableHasherResult>(&self,
26 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
27 hasher: &mut StableHasher<W>) {
28 (&self[..]).hash_stable(hcx, hasher);
32 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
33 for ty::subst::Kind<'gcx> {
34 fn hash_stable<W: StableHasherResult>(&self,
35 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
36 hasher: &mut StableHasher<W>) {
37 self.as_type().hash_stable(hcx, hasher);
38 self.as_region().hash_stable(hcx, hasher);
42 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
44 fn hash_stable<W: StableHasherResult>(&self,
45 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
46 hasher: &mut StableHasher<W>) {
47 mem::discriminant(self).hash_stable(hcx, hasher);
52 // No variant fields to hash for these ...
54 ty::ReLateBound(db, ty::BrAnon(i)) => {
55 db.depth.hash_stable(hcx, hasher);
56 i.hash_stable(hcx, hasher);
58 ty::ReLateBound(db, ty::BrNamed(def_id, name)) => {
59 db.depth.hash_stable(hcx, hasher);
60 def_id.hash_stable(hcx, hasher);
61 name.hash_stable(hcx, hasher);
63 ty::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
64 def_id.hash_stable(hcx, hasher);
65 index.hash_stable(hcx, hasher);
66 name.hash_stable(hcx, hasher);
68 ty::ReScope(code_extent) => {
69 code_extent.hash_stable(hcx, hasher);
71 ty::ReFree(ref free_region) => {
72 free_region.hash_stable(hcx, hasher);
76 ty::ReSkolemized(..) => {
77 bug!("TypeIdHasher: unexpected region {:?}", *self)
83 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
84 for ty::adjustment::AutoBorrow<'gcx> {
85 fn hash_stable<W: StableHasherResult>(&self,
86 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
87 hasher: &mut StableHasher<W>) {
88 mem::discriminant(self).hash_stable(hcx, hasher);
90 ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
91 region.hash_stable(hcx, hasher);
92 mutability.hash_stable(hcx, hasher);
94 ty::adjustment::AutoBorrow::RawPtr(mutability) => {
95 mutability.hash_stable(hcx, hasher);
101 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
102 for ty::adjustment::Adjust<'gcx> {
103 fn hash_stable<W: StableHasherResult>(&self,
104 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
105 hasher: &mut StableHasher<W>) {
106 mem::discriminant(self).hash_stable(hcx, hasher);
108 ty::adjustment::Adjust::NeverToAny |
109 ty::adjustment::Adjust::ReifyFnPointer |
110 ty::adjustment::Adjust::UnsafeFnPointer |
111 ty::adjustment::Adjust::ClosureFnPointer |
112 ty::adjustment::Adjust::MutToConstPointer |
113 ty::adjustment::Adjust::Unsize => {}
114 ty::adjustment::Adjust::Deref(ref overloaded) => {
115 overloaded.hash_stable(hcx, hasher);
117 ty::adjustment::Adjust::Borrow(ref autoref) => {
118 autoref.hash_stable(hcx, hasher);
124 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
125 impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
126 impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
127 impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
129 impl_stable_hash_for!(enum ty::BorrowKind {
135 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
136 for ty::UpvarCapture<'gcx> {
137 fn hash_stable<W: StableHasherResult>(&self,
138 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
139 hasher: &mut StableHasher<W>) {
140 mem::discriminant(self).hash_stable(hcx, hasher);
142 ty::UpvarCapture::ByValue => {}
143 ty::UpvarCapture::ByRef(ref up_var_borrow) => {
144 up_var_borrow.hash_stable(hcx, hasher);
150 impl_stable_hash_for!(struct ty::FnSig<'tcx> {
157 impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Binder<T>
158 where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
160 fn hash_stable<W: StableHasherResult>(&self,
161 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
162 hasher: &mut StableHasher<W>) {
163 let ty::Binder(ref inner) = *self;
164 inner.hash_stable(hcx, hasher);
168 impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
170 impl_stable_hash_for!(enum ty::Visibility {
176 impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
177 impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
178 impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 });
179 impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
181 impl<'a, 'gcx, 'tcx, A, B> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
182 for ty::OutlivesPredicate<A, B>
183 where A: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
184 B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
186 fn hash_stable<W: StableHasherResult>(&self,
187 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
188 hasher: &mut StableHasher<W>) {
189 let ty::OutlivesPredicate(ref a, ref b) = *self;
190 a.hash_stable(hcx, hasher);
191 b.hash_stable(hcx, hasher);
195 impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
196 impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
199 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Predicate<'gcx> {
200 fn hash_stable<W: StableHasherResult>(&self,
201 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
202 hasher: &mut StableHasher<W>) {
203 mem::discriminant(self).hash_stable(hcx, hasher);
205 ty::Predicate::Trait(ref pred) => {
206 pred.hash_stable(hcx, hasher);
208 ty::Predicate::Equate(ref pred) => {
209 pred.hash_stable(hcx, hasher);
211 ty::Predicate::Subtype(ref pred) => {
212 pred.hash_stable(hcx, hasher);
214 ty::Predicate::RegionOutlives(ref pred) => {
215 pred.hash_stable(hcx, hasher);
217 ty::Predicate::TypeOutlives(ref pred) => {
218 pred.hash_stable(hcx, hasher);
220 ty::Predicate::Projection(ref pred) => {
221 pred.hash_stable(hcx, hasher);
223 ty::Predicate::WellFormed(ty) => {
224 ty.hash_stable(hcx, hasher);
226 ty::Predicate::ObjectSafe(def_id) => {
227 def_id.hash_stable(hcx, hasher);
229 ty::Predicate::ClosureKind(def_id, closure_kind) => {
230 def_id.hash_stable(hcx, hasher);
231 closure_kind.hash_stable(hcx, hasher);
237 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::AdtFlags {
238 fn hash_stable<W: StableHasherResult>(&self,
239 _: &mut StableHashingContext<'a, 'gcx, 'tcx>,
240 hasher: &mut StableHasher<W>) {
241 std_hash::Hash::hash(self, hasher);
245 impl_stable_hash_for!(struct ty::VariantDef {
253 impl_stable_hash_for!(enum ty::VariantDiscr {
258 impl_stable_hash_for!(struct ty::FieldDef {
264 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
265 for ::middle::const_val::ConstVal<'gcx> {
266 fn hash_stable<W: StableHasherResult>(&self,
267 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
268 hasher: &mut StableHasher<W>) {
269 use middle::const_val::ConstVal;
271 mem::discriminant(self).hash_stable(hcx, hasher);
274 ConstVal::Float(ref value) => {
275 value.hash_stable(hcx, hasher);
277 ConstVal::Integral(ref value) => {
278 value.hash_stable(hcx, hasher);
280 ConstVal::Str(ref value) => {
281 value.hash_stable(hcx, hasher);
283 ConstVal::ByteStr(ref value) => {
284 value.hash_stable(hcx, hasher);
286 ConstVal::Bool(value) => {
287 value.hash_stable(hcx, hasher);
289 ConstVal::Char(value) => {
290 value.hash_stable(hcx, hasher);
292 ConstVal::Variant(def_id) => {
293 def_id.hash_stable(hcx, hasher);
295 ConstVal::Function(def_id, substs) => {
296 def_id.hash_stable(hcx, hasher);
297 substs.hash_stable(hcx, hasher);
299 ConstVal::Struct(ref name_value_map) => {
300 let mut values: Vec<(InternedString, &ConstVal)> =
301 name_value_map.iter()
302 .map(|(name, val)| (name.as_str(), val))
305 values.sort_unstable_by_key(|&(ref name, _)| name.clone());
306 values.hash_stable(hcx, hasher);
308 ConstVal::Tuple(ref value) => {
309 value.hash_stable(hcx, hasher);
311 ConstVal::Array(ref value) => {
312 value.hash_stable(hcx, hasher);
314 ConstVal::Repeat(ref value, times) => {
315 value.hash_stable(hcx, hasher);
316 times.hash_stable(hcx, hasher);
322 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
324 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
329 impl_stable_hash_for!(enum ty::Variance {
336 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
340 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Generics {
341 fn hash_stable<W: StableHasherResult>(&self,
342 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
343 hasher: &mut StableHasher<W>) {
351 // Reverse map to each `TypeParameterDef`'s `index` field, from
352 // `def_id.index` (`def_id.krate` is the same as the item's).
353 type_param_to_index: _, // Don't hash this
355 has_late_bound_regions,
358 parent.hash_stable(hcx, hasher);
359 parent_regions.hash_stable(hcx, hasher);
360 parent_types.hash_stable(hcx, hasher);
361 regions.hash_stable(hcx, hasher);
362 types.hash_stable(hcx, hasher);
363 has_self.hash_stable(hcx, hasher);
364 has_late_bound_regions.hash_stable(hcx, hasher);
368 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
369 for ty::RegionParameterDef {
370 fn hash_stable<W: StableHasherResult>(&self,
371 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
372 hasher: &mut StableHasher<W>) {
373 let ty::RegionParameterDef {
380 name.hash_stable(hcx, hasher);
381 def_id.hash_stable(hcx, hasher);
382 index.hash_stable(hcx, hasher);
383 pure_wrt_drop.hash_stable(hcx, hasher);
387 impl_stable_hash_for!(struct ty::TypeParameterDef {
392 object_lifetime_default,
397 impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
398 for ::middle::resolve_lifetime::Set1<T>
399 where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
401 fn hash_stable<W: StableHasherResult>(&self,
402 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
403 hasher: &mut StableHasher<W>) {
404 use middle::resolve_lifetime::Set1;
406 mem::discriminant(self).hash_stable(hcx, hasher);
412 Set1::One(ref value) => {
413 value.hash_stable(hcx, hasher);
419 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
421 EarlyBound(index, decl),
422 LateBound(db_index, decl),
423 LateBoundAnon(db_index, anon_index),
424 Free(call_site_scope_data, decl)
427 impl_stable_hash_for!(struct ty::DebruijnIndex {
431 impl_stable_hash_for!(enum ty::cast::CastKind {
445 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
446 for ::middle::region::CodeExtent
448 fn hash_stable<W: StableHasherResult>(&self,
449 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
450 hasher: &mut StableHasher<W>) {
451 use middle::region::CodeExtent;
453 mem::discriminant(self).hash_stable(hcx, hasher);
455 CodeExtent::Misc(node_id) |
456 CodeExtent::DestructionScope(node_id) => {
457 node_id.hash_stable(hcx, hasher);
459 CodeExtent::CallSiteScope(body_id) |
460 CodeExtent::ParameterScope(body_id) => {
461 body_id.hash_stable(hcx, hasher);
463 CodeExtent::Remainder(block_remainder) => {
464 block_remainder.hash_stable(hcx, hasher);
470 impl_stable_hash_for!(struct ::middle::region::BlockRemainder {
472 first_statement_index
475 impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
479 impl_stable_hash_for!(struct ty::FreeRegion {
484 impl_stable_hash_for!(enum ty::BoundRegion {
486 BrNamed(def_id, name),
491 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
492 for ty::TypeVariants<'gcx>
494 fn hash_stable<W: StableHasherResult>(&self,
495 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
496 hasher: &mut StableHasher<W>) {
497 use ty::TypeVariants::*;
499 mem::discriminant(self).hash_stable(hcx, hasher);
505 // Nothing more to hash.
508 int_ty.hash_stable(hcx, hasher);
511 uint_ty.hash_stable(hcx, hasher);
513 TyFloat(float_ty) => {
514 float_ty.hash_stable(hcx, hasher);
516 TyAdt(adt_def, substs) => {
517 adt_def.hash_stable(hcx, hasher);
518 substs.hash_stable(hcx, hasher);
520 TyArray(inner_ty, len) => {
521 inner_ty.hash_stable(hcx, hasher);
522 len.hash_stable(hcx, hasher);
524 TySlice(inner_ty) => {
525 inner_ty.hash_stable(hcx, hasher);
527 TyRawPtr(pointee_ty) => {
528 pointee_ty.hash_stable(hcx, hasher);
530 TyRef(region, pointee_ty) => {
531 region.hash_stable(hcx, hasher);
532 pointee_ty.hash_stable(hcx, hasher);
534 TyFnDef(def_id, substs) => {
535 def_id.hash_stable(hcx, hasher);
536 substs.hash_stable(hcx, hasher);
538 TyFnPtr(ref sig) => {
539 sig.hash_stable(hcx, hasher);
541 TyDynamic(ref existential_predicates, region) => {
542 existential_predicates.hash_stable(hcx, hasher);
543 region.hash_stable(hcx, hasher);
545 TyClosure(def_id, closure_substs) => {
546 def_id.hash_stable(hcx, hasher);
547 closure_substs.hash_stable(hcx, hasher);
549 TyTuple(inner_tys, from_diverging_type_var) => {
550 inner_tys.hash_stable(hcx, hasher);
551 from_diverging_type_var.hash_stable(hcx, hasher);
553 TyProjection(ref projection_ty) => {
554 projection_ty.hash_stable(hcx, hasher);
556 TyAnon(def_id, substs) => {
557 def_id.hash_stable(hcx, hasher);
558 substs.hash_stable(hcx, hasher);
560 TyParam(param_ty) => {
561 param_ty.hash_stable(hcx, hasher);
566 bug!("ty::TypeVariants::hash_stable() - Unexpected variant.")
572 impl_stable_hash_for!(struct ty::ParamTy {
577 impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
582 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
583 for ty::ExistentialPredicate<'gcx>
585 fn hash_stable<W: StableHasherResult>(&self,
586 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
587 hasher: &mut StableHasher<W>) {
588 mem::discriminant(self).hash_stable(hcx, hasher);
590 ty::ExistentialPredicate::Trait(ref trait_ref) => {
591 trait_ref.hash_stable(hcx, hasher);
593 ty::ExistentialPredicate::Projection(ref projection) => {
594 projection.hash_stable(hcx, hasher);
596 ty::ExistentialPredicate::AutoTrait(def_id) => {
597 def_id.hash_stable(hcx, hasher);
603 impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
608 impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
615 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
616 for ty::TypeckTables<'gcx> {
617 fn hash_stable<W: StableHasherResult>(&self,
618 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
619 hasher: &mut StableHasher<W>) {
620 let ty::TypeckTables {
622 ref type_dependent_defs,
626 ref pat_binding_modes,
627 ref upvar_capture_map,
630 ref liberated_fn_sigs,
635 ref used_trait_imports,
640 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
641 ich::hash_stable_itemlocalmap(hcx, hasher, type_dependent_defs);
642 ich::hash_stable_itemlocalmap(hcx, hasher, node_types);
643 ich::hash_stable_itemlocalmap(hcx, hasher, node_substs);
644 ich::hash_stable_itemlocalmap(hcx, hasher, adjustments);
645 ich::hash_stable_itemlocalmap(hcx, hasher, pat_binding_modes);
646 ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
652 let var_def_id = hcx.tcx().hir.local_def_id(var_id);
653 let closure_def_id = hcx.tcx().hir.local_def_id(closure_expr_id);
654 (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
657 ich::hash_stable_itemlocalmap(hcx, hasher, closure_tys);
658 ich::hash_stable_itemlocalmap(hcx, hasher, closure_kinds);
659 ich::hash_stable_itemlocalmap(hcx, hasher, liberated_fn_sigs);
660 ich::hash_stable_itemlocalmap(hcx, hasher, fru_field_types);
661 ich::hash_stable_nodemap(hcx, hasher, cast_kinds);
663 ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| {
664 hcx.def_path_hash(*def_id)
667 tainted_by_errors.hash_stable(hcx, hasher);
668 free_region_map.hash_stable(hcx, hasher);
673 impl_stable_hash_for!(enum ty::fast_reject::SimplifiedType {
676 IntSimplifiedType(int_ty),
677 UintSimplifiedType(int_ty),
678 FloatSimplifiedType(float_ty),
679 AdtSimplifiedType(def_id),
684 TupleSimplifiedType(size),
685 TraitSimplifiedType(def_id),
686 ClosureSimplifiedType(def_id),
687 AnonSimplifiedType(def_id),
688 FunctionSimplifiedType(params),
689 ParameterSimplifiedType
692 impl_stable_hash_for!(struct ty::Instance<'tcx> {
697 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::InstanceDef<'gcx> {
698 fn hash_stable<W: StableHasherResult>(&self,
699 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
700 hasher: &mut StableHasher<W>) {
701 mem::discriminant(self).hash_stable(hcx, hasher);
704 ty::InstanceDef::Item(def_id) => {
705 def_id.hash_stable(hcx, hasher);
707 ty::InstanceDef::Intrinsic(def_id) => {
708 def_id.hash_stable(hcx, hasher);
710 ty::InstanceDef::FnPtrShim(def_id, ty) => {
711 def_id.hash_stable(hcx, hasher);
712 ty.hash_stable(hcx, hasher);
714 ty::InstanceDef::Virtual(def_id, n) => {
715 def_id.hash_stable(hcx, hasher);
716 n.hash_stable(hcx, hasher);
718 ty::InstanceDef::ClosureOnceShim { call_once } => {
719 call_once.hash_stable(hcx, hasher);
721 ty::InstanceDef::DropGlue(def_id, t) => {
722 def_id.hash_stable(hcx, hasher);
723 t.hash_stable(hcx, hasher);