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_stable_hash_for!(struct ty::ItemSubsts<'tcx> { substs });
24 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for &'tcx ty::Slice<T>
25 where T: HashStable<StableHashingContext<'a, 'tcx>> {
26 fn hash_stable<W: StableHasherResult>(&self,
27 hcx: &mut StableHashingContext<'a, 'tcx>,
28 hasher: &mut StableHasher<W>) {
29 (&self[..]).hash_stable(hcx, hasher);
33 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::subst::Kind<'tcx> {
34 fn hash_stable<W: StableHasherResult>(&self,
35 hcx: &mut StableHashingContext<'a, '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, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Region {
43 fn hash_stable<W: StableHasherResult>(&self,
44 hcx: &mut StableHashingContext<'a, 'tcx>,
45 hasher: &mut StableHasher<W>) {
46 mem::discriminant(self).hash_stable(hcx, hasher);
51 // No variant fields to hash for these ...
53 ty::ReLateBound(db, ty::BrAnon(i)) => {
54 db.depth.hash_stable(hcx, hasher);
55 i.hash_stable(hcx, hasher);
57 ty::ReEarlyBound(ty::EarlyBoundRegion { index, name }) => {
58 index.hash_stable(hcx, hasher);
59 name.hash_stable(hcx, hasher);
61 ty::ReScope(code_extent) => {
62 code_extent.hash_stable(hcx, hasher);
64 ty::ReFree(ref free_region) => {
65 free_region.hash_stable(hcx, hasher);
69 ty::ReSkolemized(..) => {
70 bug!("TypeIdHasher: unexpected region {:?}", *self)
76 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::AutoBorrow<'tcx> {
77 fn hash_stable<W: StableHasherResult>(&self,
78 hcx: &mut StableHashingContext<'a, 'tcx>,
79 hasher: &mut StableHasher<W>) {
80 mem::discriminant(self).hash_stable(hcx, hasher);
82 ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
83 region.hash_stable(hcx, hasher);
84 mutability.hash_stable(hcx, hasher);
86 ty::adjustment::AutoBorrow::RawPtr(mutability) => {
87 mutability.hash_stable(hcx, hasher);
93 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::Adjust<'tcx> {
94 fn hash_stable<W: StableHasherResult>(&self,
95 hcx: &mut StableHashingContext<'a, 'tcx>,
96 hasher: &mut StableHasher<W>) {
97 mem::discriminant(self).hash_stable(hcx, hasher);
99 ty::adjustment::Adjust::NeverToAny |
100 ty::adjustment::Adjust::ReifyFnPointer |
101 ty::adjustment::Adjust::UnsafeFnPointer |
102 ty::adjustment::Adjust::ClosureFnPointer |
103 ty::adjustment::Adjust::MutToConstPointer => {}
104 ty::adjustment::Adjust::DerefRef { autoderefs, ref autoref, unsize } => {
105 autoderefs.hash_stable(hcx, hasher);
106 autoref.hash_stable(hcx, hasher);
107 unsize.hash_stable(hcx, hasher);
113 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
114 impl_stable_hash_for!(struct ty::MethodCall { expr_id, autoderef });
115 impl_stable_hash_for!(struct ty::MethodCallee<'tcx> { def_id, ty, substs });
116 impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
117 impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
119 impl_stable_hash_for!(enum ty::BorrowKind {
125 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::UpvarCapture<'tcx> {
126 fn hash_stable<W: StableHasherResult>(&self,
127 hcx: &mut StableHashingContext<'a, 'tcx>,
128 hasher: &mut StableHasher<W>) {
129 mem::discriminant(self).hash_stable(hcx, hasher);
131 ty::UpvarCapture::ByValue => {}
132 ty::UpvarCapture::ByRef(ref up_var_borrow) => {
133 up_var_borrow.hash_stable(hcx, hasher);
139 impl_stable_hash_for!(struct ty::FnSig<'tcx> {
146 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for ty::Binder<T>
147 where T: HashStable<StableHashingContext<'a, 'tcx>> + ty::fold::TypeFoldable<'tcx>
149 fn hash_stable<W: StableHasherResult>(&self,
150 hcx: &mut StableHashingContext<'a, 'tcx>,
151 hasher: &mut StableHasher<W>) {
152 hcx.tcx().anonymize_late_bound_regions(self).0.hash_stable(hcx, hasher);
156 impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
158 impl_stable_hash_for!(enum ty::Visibility {
164 impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
165 impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
166 impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 });
168 impl<'a, 'tcx, A, B> HashStable<StableHashingContext<'a, 'tcx>> for ty::OutlivesPredicate<A, B>
169 where A: HashStable<StableHashingContext<'a, 'tcx>>,
170 B: HashStable<StableHashingContext<'a, 'tcx>>,
172 fn hash_stable<W: StableHasherResult>(&self,
173 hcx: &mut StableHashingContext<'a, 'tcx>,
174 hasher: &mut StableHasher<W>) {
175 let ty::OutlivesPredicate(ref a, ref b) = *self;
176 a.hash_stable(hcx, hasher);
177 b.hash_stable(hcx, hasher);
181 impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
182 impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_name });
185 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Predicate<'tcx> {
186 fn hash_stable<W: StableHasherResult>(&self,
187 hcx: &mut StableHashingContext<'a, 'tcx>,
188 hasher: &mut StableHasher<W>) {
189 mem::discriminant(self).hash_stable(hcx, hasher);
191 ty::Predicate::Trait(ref pred) => {
192 pred.hash_stable(hcx, hasher);
194 ty::Predicate::Equate(ref pred) => {
195 pred.hash_stable(hcx, hasher);
197 ty::Predicate::RegionOutlives(ref pred) => {
198 pred.hash_stable(hcx, hasher);
200 ty::Predicate::TypeOutlives(ref pred) => {
201 pred.hash_stable(hcx, hasher);
203 ty::Predicate::Projection(ref pred) => {
204 pred.hash_stable(hcx, hasher);
206 ty::Predicate::WellFormed(ty) => {
207 ty.hash_stable(hcx, hasher);
209 ty::Predicate::ObjectSafe(def_id) => {
210 def_id.hash_stable(hcx, hasher);
212 ty::Predicate::ClosureKind(def_id, closure_kind) => {
213 def_id.hash_stable(hcx, hasher);
214 closure_kind.hash_stable(hcx, hasher);
220 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::AdtFlags {
221 fn hash_stable<W: StableHasherResult>(&self,
222 _: &mut StableHashingContext<'a, 'tcx>,
223 hasher: &mut StableHasher<W>) {
224 std_hash::Hash::hash(self, hasher);
228 impl_stable_hash_for!(struct ty::VariantDef {
236 impl_stable_hash_for!(enum ty::VariantDiscr {
241 impl_stable_hash_for!(struct ty::FieldDef {
247 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>>
248 for ::middle::const_val::ConstVal<'tcx> {
249 fn hash_stable<W: StableHasherResult>(&self,
250 hcx: &mut StableHashingContext<'a, 'tcx>,
251 hasher: &mut StableHasher<W>) {
252 use middle::const_val::ConstVal;
254 mem::discriminant(self).hash_stable(hcx, hasher);
257 ConstVal::Float(ref value) => {
258 value.hash_stable(hcx, hasher);
260 ConstVal::Integral(ref value) => {
261 value.hash_stable(hcx, hasher);
263 ConstVal::Str(ref value) => {
264 value.hash_stable(hcx, hasher);
266 ConstVal::ByteStr(ref value) => {
267 value.hash_stable(hcx, hasher);
269 ConstVal::Bool(value) => {
270 value.hash_stable(hcx, hasher);
272 ConstVal::Function(def_id, substs) => {
273 def_id.hash_stable(hcx, hasher);
274 substs.hash_stable(hcx, hasher);
276 ConstVal::Struct(ref name_value_map) => {
277 let mut values: Vec<(InternedString, &ConstVal)> =
278 name_value_map.iter()
279 .map(|(name, val)| (name.as_str(), val))
282 values.sort_unstable_by_key(|&(ref name, _)| name.clone());
283 values.hash_stable(hcx, hasher);
285 ConstVal::Tuple(ref value) => {
286 value.hash_stable(hcx, hasher);
288 ConstVal::Array(ref value) => {
289 value.hash_stable(hcx, hasher);
291 ConstVal::Repeat(ref value, times) => {
292 value.hash_stable(hcx, hasher);
293 times.hash_stable(hcx, hasher);
295 ConstVal::Char(value) => {
296 value.hash_stable(hcx, hasher);
302 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
304 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
309 impl_stable_hash_for!(enum ty::Variance {
316 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
320 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Generics {
321 fn hash_stable<W: StableHasherResult>(&self,
322 hcx: &mut StableHashingContext<'a, 'tcx>,
323 hasher: &mut StableHasher<W>) {
331 // Reverse map to each `TypeParameterDef`'s `index` field, from
332 // `def_id.index` (`def_id.krate` is the same as the item's).
333 type_param_to_index: _, // Don't hash this
337 parent.hash_stable(hcx, hasher);
338 parent_regions.hash_stable(hcx, hasher);
339 parent_types.hash_stable(hcx, hasher);
340 regions.hash_stable(hcx, hasher);
341 types.hash_stable(hcx, hasher);
342 has_self.hash_stable(hcx, hasher);
346 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionParameterDef {
347 fn hash_stable<W: StableHasherResult>(&self,
348 hcx: &mut StableHashingContext<'a, 'tcx>,
349 hasher: &mut StableHasher<W>) {
350 let ty::RegionParameterDef {
358 name.hash_stable(hcx, hasher);
359 def_id.hash_stable(hcx, hasher);
360 index.hash_stable(hcx, hasher);
361 pure_wrt_drop.hash_stable(hcx, hasher);
365 impl_stable_hash_for!(struct ty::TypeParameterDef {
370 object_lifetime_default,
375 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>>
376 for ::middle::resolve_lifetime::Set1<T>
377 where T: HashStable<StableHashingContext<'a, 'tcx>>
379 fn hash_stable<W: StableHasherResult>(&self,
380 hcx: &mut StableHashingContext<'a, 'tcx>,
381 hasher: &mut StableHasher<W>) {
382 use middle::resolve_lifetime::Set1;
384 mem::discriminant(self).hash_stable(hcx, hasher);
390 Set1::One(ref value) => {
391 value.hash_stable(hcx, hasher);
397 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
399 EarlyBound(index, decl),
400 LateBound(db_index, decl),
401 LateBoundAnon(db_index, anon_index),
402 Free(call_site_scope_data, decl)
405 impl_stable_hash_for!(struct ::middle::region::CallSiteScopeData {
410 impl_stable_hash_for!(struct ty::DebruijnIndex {
414 impl_stable_hash_for!(enum ty::cast::CastKind {
428 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtent
430 fn hash_stable<W: StableHasherResult>(&self,
431 hcx: &mut StableHashingContext<'a, 'tcx>,
432 hasher: &mut StableHasher<W>) {
433 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
434 hcx.tcx().region_maps.code_extent_data(*self).hash_stable(hcx, hasher);
439 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtentData
441 fn hash_stable<W: StableHasherResult>(&self,
442 hcx: &mut StableHashingContext<'a, 'tcx>,
443 hasher: &mut StableHasher<W>) {
444 use middle::region::CodeExtentData;
446 mem::discriminant(self).hash_stable(hcx, hasher);
448 CodeExtentData::Misc(node_id) |
449 CodeExtentData::DestructionScope(node_id) => {
450 node_id.hash_stable(hcx, hasher);
452 CodeExtentData::CallSiteScope { fn_id, body_id } |
453 CodeExtentData::ParameterScope { fn_id, body_id } => {
454 fn_id.hash_stable(hcx, hasher);
455 body_id.hash_stable(hcx, hasher);
457 CodeExtentData::Remainder(block_remainder) => {
458 block_remainder.hash_stable(hcx, hasher);
464 impl_stable_hash_for!(struct ::middle::region::BlockRemainder {
466 first_statement_index
469 impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
473 impl_stable_hash_for!(struct ty::FreeRegion {
478 impl_stable_hash_for!(enum ty::BoundRegion {
480 BrNamed(def_id, name),
485 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeVariants<'tcx>
487 fn hash_stable<W: StableHasherResult>(&self,
488 hcx: &mut StableHashingContext<'a, '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, ref sig) => {
528 def_id.hash_stable(hcx, hasher);
529 substs.hash_stable(hcx, hasher);
530 sig.hash_stable(hcx, hasher);
532 TyFnPtr(ref sig) => {
533 sig.hash_stable(hcx, hasher);
535 TyDynamic(ref existential_predicates, region) => {
536 existential_predicates.hash_stable(hcx, hasher);
537 region.hash_stable(hcx, hasher);
539 TyClosure(def_id, closure_substs) => {
540 def_id.hash_stable(hcx, hasher);
541 closure_substs.hash_stable(hcx, hasher);
543 TyTuple(inner_tys, from_diverging_type_var) => {
544 inner_tys.hash_stable(hcx, hasher);
545 from_diverging_type_var.hash_stable(hcx, hasher);
547 TyProjection(ref projection_ty) => {
548 projection_ty.hash_stable(hcx, hasher);
550 TyAnon(def_id, substs) => {
551 def_id.hash_stable(hcx, hasher);
552 substs.hash_stable(hcx, hasher);
554 TyParam(param_ty) => {
555 param_ty.hash_stable(hcx, hasher);
560 bug!("ty::TypeVariants::hash_stable() - Unexpected variant.")
566 impl_stable_hash_for!(struct ty::ParamTy {
571 impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
576 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::ExistentialPredicate<'tcx>
578 fn hash_stable<W: StableHasherResult>(&self,
579 hcx: &mut StableHashingContext<'a, '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, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<'tcx> {
609 fn hash_stable<W: StableHasherResult>(&self,
610 hcx: &mut StableHashingContext<'a, 'tcx>,
611 hasher: &mut StableHasher<W>) {
612 let ty::TypeckTables {
613 ref type_relative_path_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_relative_path_defs);
635 ich::hash_stable_nodemap(hcx, hasher, node_types);
636 ich::hash_stable_nodemap(hcx, hasher, item_substs);
637 ich::hash_stable_nodemap(hcx, hasher, adjustments);
639 ich::hash_stable_hashmap(hcx, hasher, method_map, |hcx, method_call| {
645 let def_id = hcx.tcx().hir.local_def_id(expr_id);
646 (hcx.def_path_hash(def_id), autoderef)
649 ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
655 let var_def_id = hcx.tcx().hir.local_def_id(var_id);
656 let closure_def_id = hcx.tcx().hir.local_def_id(closure_expr_id);
657 (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
660 ich::hash_stable_nodemap(hcx, hasher, closure_tys);
661 ich::hash_stable_nodemap(hcx, hasher, closure_kinds);
662 ich::hash_stable_nodemap(hcx, hasher, liberated_fn_sigs);
663 ich::hash_stable_nodemap(hcx, hasher, fru_field_types);
664 ich::hash_stable_nodemap(hcx, hasher, cast_kinds);
666 ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| {
667 hcx.def_path_hash(*def_id)
670 tainted_by_errors.hash_stable(hcx, hasher);
671 free_region_map.hash_stable(hcx, hasher);