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 &'tcx 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<'tcx> {
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::ReEarlyBound(ty::EarlyBoundRegion { def_id, index, name }) => {
59 def_id.hash_stable(hcx, hasher);
60 index.hash_stable(hcx, hasher);
61 name.hash_stable(hcx, hasher);
63 ty::ReScope(code_extent) => {
64 code_extent.hash_stable(hcx, hasher);
66 ty::ReFree(ref free_region) => {
67 free_region.hash_stable(hcx, hasher);
71 ty::ReSkolemized(..) => {
72 bug!("TypeIdHasher: unexpected region {:?}", *self)
78 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
79 for ty::adjustment::AutoBorrow<'tcx> {
80 fn hash_stable<W: StableHasherResult>(&self,
81 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
82 hasher: &mut StableHasher<W>) {
83 mem::discriminant(self).hash_stable(hcx, hasher);
85 ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
86 region.hash_stable(hcx, hasher);
87 mutability.hash_stable(hcx, hasher);
89 ty::adjustment::AutoBorrow::RawPtr(mutability) => {
90 mutability.hash_stable(hcx, hasher);
96 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
97 for ty::adjustment::Adjust<'tcx> {
98 fn hash_stable<W: StableHasherResult>(&self,
99 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
100 hasher: &mut StableHasher<W>) {
101 mem::discriminant(self).hash_stable(hcx, hasher);
103 ty::adjustment::Adjust::NeverToAny |
104 ty::adjustment::Adjust::ReifyFnPointer |
105 ty::adjustment::Adjust::UnsafeFnPointer |
106 ty::adjustment::Adjust::ClosureFnPointer |
107 ty::adjustment::Adjust::MutToConstPointer |
108 ty::adjustment::Adjust::Unsize => {}
109 ty::adjustment::Adjust::Deref(ref overloaded) => {
110 overloaded.hash_stable(hcx, hasher);
112 ty::adjustment::Adjust::Borrow(ref autoref) => {
113 autoref.hash_stable(hcx, hasher);
119 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
120 impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl });
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 {
130 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
131 for ty::UpvarCapture<'tcx> {
132 fn hash_stable<W: StableHasherResult>(&self,
133 hcx: &mut StableHashingContext<'a, 'gcx, '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, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Binder<T>
153 where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + ty::fold::TypeFoldable<'tcx>
155 fn hash_stable<W: StableHasherResult>(&self,
156 hcx: &mut StableHashingContext<'a, 'gcx, '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 });
173 impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
175 impl<'a, 'gcx, 'tcx, A, B> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
176 for ty::OutlivesPredicate<A, B>
177 where A: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
178 B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>,
180 fn hash_stable<W: StableHasherResult>(&self,
181 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
182 hasher: &mut StableHasher<W>) {
183 let ty::OutlivesPredicate(ref a, ref b) = *self;
184 a.hash_stable(hcx, hasher);
185 b.hash_stable(hcx, hasher);
189 impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
190 impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
193 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Predicate<'tcx> {
194 fn hash_stable<W: StableHasherResult>(&self,
195 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
196 hasher: &mut StableHasher<W>) {
197 mem::discriminant(self).hash_stable(hcx, hasher);
199 ty::Predicate::Trait(ref pred) => {
200 pred.hash_stable(hcx, hasher);
202 ty::Predicate::Equate(ref pred) => {
203 pred.hash_stable(hcx, hasher);
205 ty::Predicate::Subtype(ref pred) => {
206 pred.hash_stable(hcx, hasher);
208 ty::Predicate::RegionOutlives(ref pred) => {
209 pred.hash_stable(hcx, hasher);
211 ty::Predicate::TypeOutlives(ref pred) => {
212 pred.hash_stable(hcx, hasher);
214 ty::Predicate::Projection(ref pred) => {
215 pred.hash_stable(hcx, hasher);
217 ty::Predicate::WellFormed(ty) => {
218 ty.hash_stable(hcx, hasher);
220 ty::Predicate::ObjectSafe(def_id) => {
221 def_id.hash_stable(hcx, hasher);
223 ty::Predicate::ClosureKind(def_id, closure_kind) => {
224 def_id.hash_stable(hcx, hasher);
225 closure_kind.hash_stable(hcx, hasher);
231 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::AdtFlags {
232 fn hash_stable<W: StableHasherResult>(&self,
233 _: &mut StableHashingContext<'a, 'gcx, 'tcx>,
234 hasher: &mut StableHasher<W>) {
235 std_hash::Hash::hash(self, hasher);
239 impl_stable_hash_for!(struct ty::VariantDef {
247 impl_stable_hash_for!(enum ty::VariantDiscr {
252 impl_stable_hash_for!(struct ty::FieldDef {
258 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
259 for ::middle::const_val::ConstVal<'tcx> {
260 fn hash_stable<W: StableHasherResult>(&self,
261 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
262 hasher: &mut StableHasher<W>) {
263 use middle::const_val::ConstVal;
265 mem::discriminant(self).hash_stable(hcx, hasher);
268 ConstVal::Float(ref value) => {
269 value.hash_stable(hcx, hasher);
271 ConstVal::Integral(ref value) => {
272 value.hash_stable(hcx, hasher);
274 ConstVal::Str(ref value) => {
275 value.hash_stable(hcx, hasher);
277 ConstVal::ByteStr(ref value) => {
278 value.hash_stable(hcx, hasher);
280 ConstVal::Bool(value) => {
281 value.hash_stable(hcx, hasher);
283 ConstVal::Char(value) => {
284 value.hash_stable(hcx, hasher);
286 ConstVal::Variant(def_id) => {
287 def_id.hash_stable(hcx, hasher);
289 ConstVal::Function(def_id, substs) => {
290 def_id.hash_stable(hcx, hasher);
291 substs.hash_stable(hcx, hasher);
293 ConstVal::Struct(ref name_value_map) => {
294 let mut values: Vec<(InternedString, &ConstVal)> =
295 name_value_map.iter()
296 .map(|(name, val)| (name.as_str(), val))
299 values.sort_unstable_by_key(|&(ref name, _)| name.clone());
300 values.hash_stable(hcx, hasher);
302 ConstVal::Tuple(ref value) => {
303 value.hash_stable(hcx, hasher);
305 ConstVal::Array(ref value) => {
306 value.hash_stable(hcx, hasher);
308 ConstVal::Repeat(ref value, times) => {
309 value.hash_stable(hcx, hasher);
310 times.hash_stable(hcx, hasher);
316 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
318 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
323 impl_stable_hash_for!(enum ty::Variance {
330 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
334 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Generics {
335 fn hash_stable<W: StableHasherResult>(&self,
336 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
337 hasher: &mut StableHasher<W>) {
345 // Reverse map to each `TypeParameterDef`'s `index` field, from
346 // `def_id.index` (`def_id.krate` is the same as the item's).
347 type_param_to_index: _, // Don't hash this
351 parent.hash_stable(hcx, hasher);
352 parent_regions.hash_stable(hcx, hasher);
353 parent_types.hash_stable(hcx, hasher);
354 regions.hash_stable(hcx, hasher);
355 types.hash_stable(hcx, hasher);
356 has_self.hash_stable(hcx, hasher);
360 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
361 for ty::RegionParameterDef {
362 fn hash_stable<W: StableHasherResult>(&self,
363 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
364 hasher: &mut StableHasher<W>) {
365 let ty::RegionParameterDef {
373 name.hash_stable(hcx, hasher);
374 def_id.hash_stable(hcx, hasher);
375 index.hash_stable(hcx, hasher);
376 pure_wrt_drop.hash_stable(hcx, hasher);
380 impl_stable_hash_for!(struct ty::TypeParameterDef {
385 object_lifetime_default,
390 impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
391 for ::middle::resolve_lifetime::Set1<T>
392 where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
394 fn hash_stable<W: StableHasherResult>(&self,
395 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
396 hasher: &mut StableHasher<W>) {
397 use middle::resolve_lifetime::Set1;
399 mem::discriminant(self).hash_stable(hcx, hasher);
405 Set1::One(ref value) => {
406 value.hash_stable(hcx, hasher);
412 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
414 EarlyBound(index, decl),
415 LateBound(db_index, decl),
416 LateBoundAnon(db_index, anon_index),
417 Free(call_site_scope_data, decl)
420 impl_stable_hash_for!(struct ty::DebruijnIndex {
424 impl_stable_hash_for!(enum ty::cast::CastKind {
438 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
439 for ::middle::region::CodeExtent
441 fn hash_stable<W: StableHasherResult>(&self,
442 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
443 hasher: &mut StableHasher<W>) {
444 use middle::region::CodeExtent;
446 mem::discriminant(self).hash_stable(hcx, hasher);
448 CodeExtent::Misc(node_id) |
449 CodeExtent::DestructionScope(node_id) => {
450 node_id.hash_stable(hcx, hasher);
452 CodeExtent::CallSiteScope(body_id) |
453 CodeExtent::ParameterScope(body_id) => {
454 body_id.hash_stable(hcx, hasher);
456 CodeExtent::Remainder(block_remainder) => {
457 block_remainder.hash_stable(hcx, hasher);
463 impl_stable_hash_for!(struct ::middle::region::BlockRemainder {
465 first_statement_index
468 impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
472 impl_stable_hash_for!(struct ty::FreeRegion {
477 impl_stable_hash_for!(enum ty::BoundRegion {
479 BrNamed(def_id, name),
484 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
485 for ty::TypeVariants<'tcx>
487 fn hash_stable<W: StableHasherResult>(&self,
488 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
489 hasher: &mut StableHasher<W>) {
490 use ty::TypeVariants::*;
492 mem::discriminant(self).hash_stable(hcx, hasher);
498 // Nothing more to hash.
501 int_ty.hash_stable(hcx, hasher);
504 uint_ty.hash_stable(hcx, hasher);
506 TyFloat(float_ty) => {
507 float_ty.hash_stable(hcx, hasher);
509 TyAdt(adt_def, substs) => {
510 adt_def.hash_stable(hcx, hasher);
511 substs.hash_stable(hcx, hasher);
513 TyArray(inner_ty, len) => {
514 inner_ty.hash_stable(hcx, hasher);
515 len.hash_stable(hcx, hasher);
517 TySlice(inner_ty) => {
518 inner_ty.hash_stable(hcx, hasher);
520 TyRawPtr(pointee_ty) => {
521 pointee_ty.hash_stable(hcx, hasher);
523 TyRef(region, pointee_ty) => {
524 region.hash_stable(hcx, hasher);
525 pointee_ty.hash_stable(hcx, hasher);
527 TyFnDef(def_id, substs) => {
528 def_id.hash_stable(hcx, hasher);
529 substs.hash_stable(hcx, hasher);
531 TyFnPtr(ref sig) => {
532 sig.hash_stable(hcx, hasher);
534 TyDynamic(ref existential_predicates, region) => {
535 existential_predicates.hash_stable(hcx, hasher);
536 region.hash_stable(hcx, hasher);
538 TyClosure(def_id, closure_substs) => {
539 def_id.hash_stable(hcx, hasher);
540 closure_substs.hash_stable(hcx, hasher);
542 TyTuple(inner_tys, from_diverging_type_var) => {
543 inner_tys.hash_stable(hcx, hasher);
544 from_diverging_type_var.hash_stable(hcx, hasher);
546 TyProjection(ref projection_ty) => {
547 projection_ty.hash_stable(hcx, hasher);
549 TyAnon(def_id, substs) => {
550 def_id.hash_stable(hcx, hasher);
551 substs.hash_stable(hcx, hasher);
553 TyParam(param_ty) => {
554 param_ty.hash_stable(hcx, hasher);
559 bug!("ty::TypeVariants::hash_stable() - Unexpected variant.")
565 impl_stable_hash_for!(struct ty::ParamTy {
570 impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
575 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
576 for ty::ExistentialPredicate<'tcx>
578 fn hash_stable<W: StableHasherResult>(&self,
579 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
580 hasher: &mut StableHasher<W>) {
581 mem::discriminant(self).hash_stable(hcx, hasher);
583 ty::ExistentialPredicate::Trait(ref trait_ref) => {
584 trait_ref.hash_stable(hcx, hasher);
586 ty::ExistentialPredicate::Projection(ref projection) => {
587 projection.hash_stable(hcx, hasher);
589 ty::ExistentialPredicate::AutoTrait(def_id) => {
590 def_id.hash_stable(hcx, hasher);
596 impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
601 impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
608 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>>
609 for ty::TypeckTables<'tcx> {
610 fn hash_stable<W: StableHasherResult>(&self,
611 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
612 hasher: &mut StableHasher<W>) {
613 let ty::TypeckTables {
614 ref type_dependent_defs,
618 ref upvar_capture_map,
621 ref liberated_fn_sigs,
626 // FIXME(#41184): This is still ignored at the moment.
628 ref used_trait_imports,
633 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
634 ich::hash_stable_nodemap(hcx, hasher, type_dependent_defs);
635 ich::hash_stable_nodemap(hcx, hasher, node_types);
636 ich::hash_stable_nodemap(hcx, hasher, node_substs);
637 ich::hash_stable_nodemap(hcx, hasher, adjustments);
638 ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
644 let var_def_id = hcx.tcx().hir.local_def_id(var_id);
645 let closure_def_id = hcx.tcx().hir.local_def_id(closure_expr_id);
646 (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
649 ich::hash_stable_nodemap(hcx, hasher, closure_tys);
650 ich::hash_stable_nodemap(hcx, hasher, closure_kinds);
651 ich::hash_stable_nodemap(hcx, hasher, liberated_fn_sigs);
652 ich::hash_stable_nodemap(hcx, hasher, fru_field_types);
653 ich::hash_stable_nodemap(hcx, hasher, cast_kinds);
655 ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| {
656 hcx.def_path_hash(*def_id)
659 tainted_by_errors.hash_stable(hcx, hasher);
660 free_region_map.hash_stable(hcx, hasher);
665 impl_stable_hash_for!(enum ty::fast_reject::SimplifiedType {
668 IntSimplifiedType(int_ty),
669 UintSimplifiedType(int_ty),
670 FloatSimplifiedType(float_ty),
671 AdtSimplifiedType(def_id),
676 TupleSimplifiedType(size),
677 TraitSimplifiedType(def_id),
678 ClosureSimplifiedType(def_id),
679 AnonSimplifiedType(def_id),
680 FunctionSimplifiedType(params),
681 ParameterSimplifiedType
684 impl_stable_hash_for!(struct ty::Instance<'tcx> {
689 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::InstanceDef<'tcx> {
690 fn hash_stable<W: StableHasherResult>(&self,
691 hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
692 hasher: &mut StableHasher<W>) {
693 mem::discriminant(self).hash_stable(hcx, hasher);
696 ty::InstanceDef::Item(def_id) => {
697 def_id.hash_stable(hcx, hasher);
699 ty::InstanceDef::Intrinsic(def_id) => {
700 def_id.hash_stable(hcx, hasher);
702 ty::InstanceDef::FnPtrShim(def_id, ty) => {
703 def_id.hash_stable(hcx, hasher);
704 ty.hash_stable(hcx, hasher);
706 ty::InstanceDef::Virtual(def_id, n) => {
707 def_id.hash_stable(hcx, hasher);
708 n.hash_stable(hcx, hasher);
710 ty::InstanceDef::ClosureOnceShim { call_once } => {
711 call_once.hash_stable(hcx, hasher);
713 ty::InstanceDef::DropGlue(def_id, t) => {
714 def_id.hash_stable(hcx, hasher);
715 t.hash_stable(hcx, hasher);