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::RegionKind {
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 { def_id, index, name }) => {
58 def_id.hash_stable(hcx, hasher);
59 index.hash_stable(hcx, hasher);
60 name.hash_stable(hcx, hasher);
62 ty::ReScope(code_extent) => {
63 code_extent.hash_stable(hcx, hasher);
65 ty::ReFree(ref free_region) => {
66 free_region.hash_stable(hcx, hasher);
70 ty::ReSkolemized(..) => {
71 bug!("TypeIdHasher: unexpected region {:?}", *self)
77 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::AutoBorrow<'tcx> {
78 fn hash_stable<W: StableHasherResult>(&self,
79 hcx: &mut StableHashingContext<'a, 'tcx>,
80 hasher: &mut StableHasher<W>) {
81 mem::discriminant(self).hash_stable(hcx, hasher);
83 ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
84 region.hash_stable(hcx, hasher);
85 mutability.hash_stable(hcx, hasher);
87 ty::adjustment::AutoBorrow::RawPtr(mutability) => {
88 mutability.hash_stable(hcx, hasher);
94 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::Adjust<'tcx> {
95 fn hash_stable<W: StableHasherResult>(&self,
96 hcx: &mut StableHashingContext<'a, 'tcx>,
97 hasher: &mut StableHasher<W>) {
98 mem::discriminant(self).hash_stable(hcx, hasher);
100 ty::adjustment::Adjust::NeverToAny |
101 ty::adjustment::Adjust::ReifyFnPointer |
102 ty::adjustment::Adjust::UnsafeFnPointer |
103 ty::adjustment::Adjust::ClosureFnPointer |
104 ty::adjustment::Adjust::MutToConstPointer => {}
105 ty::adjustment::Adjust::DerefRef { autoderefs, ref autoref, unsize } => {
106 autoderefs.hash_stable(hcx, hasher);
107 autoref.hash_stable(hcx, hasher);
108 unsize.hash_stable(hcx, hasher);
114 impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
115 impl_stable_hash_for!(struct ty::MethodCall { expr_id, autoderef });
116 impl_stable_hash_for!(struct ty::MethodCallee<'tcx> { def_id, ty, substs });
117 impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
118 impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
120 impl_stable_hash_for!(enum ty::BorrowKind {
126 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::UpvarCapture<'tcx> {
127 fn hash_stable<W: StableHasherResult>(&self,
128 hcx: &mut StableHashingContext<'a, 'tcx>,
129 hasher: &mut StableHasher<W>) {
130 mem::discriminant(self).hash_stable(hcx, hasher);
132 ty::UpvarCapture::ByValue => {}
133 ty::UpvarCapture::ByRef(ref up_var_borrow) => {
134 up_var_borrow.hash_stable(hcx, hasher);
140 impl_stable_hash_for!(struct ty::FnSig<'tcx> {
147 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for ty::Binder<T>
148 where T: HashStable<StableHashingContext<'a, 'tcx>> + ty::fold::TypeFoldable<'tcx>
150 fn hash_stable<W: StableHasherResult>(&self,
151 hcx: &mut StableHashingContext<'a, 'tcx>,
152 hasher: &mut StableHasher<W>) {
153 hcx.tcx().anonymize_late_bound_regions(self).0.hash_stable(hcx, hasher);
157 impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
159 impl_stable_hash_for!(enum ty::Visibility {
165 impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
166 impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
167 impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 });
168 impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
170 impl<'a, 'tcx, A, B> HashStable<StableHashingContext<'a, 'tcx>> for ty::OutlivesPredicate<A, B>
171 where A: HashStable<StableHashingContext<'a, 'tcx>>,
172 B: HashStable<StableHashingContext<'a, 'tcx>>,
174 fn hash_stable<W: StableHasherResult>(&self,
175 hcx: &mut StableHashingContext<'a, 'tcx>,
176 hasher: &mut StableHasher<W>) {
177 let ty::OutlivesPredicate(ref a, ref b) = *self;
178 a.hash_stable(hcx, hasher);
179 b.hash_stable(hcx, hasher);
183 impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
184 impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_name });
187 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Predicate<'tcx> {
188 fn hash_stable<W: StableHasherResult>(&self,
189 hcx: &mut StableHashingContext<'a, 'tcx>,
190 hasher: &mut StableHasher<W>) {
191 mem::discriminant(self).hash_stable(hcx, hasher);
193 ty::Predicate::Trait(ref pred) => {
194 pred.hash_stable(hcx, hasher);
196 ty::Predicate::Equate(ref pred) => {
197 pred.hash_stable(hcx, hasher);
199 ty::Predicate::Subtype(ref pred) => {
200 pred.hash_stable(hcx, hasher);
202 ty::Predicate::RegionOutlives(ref pred) => {
203 pred.hash_stable(hcx, hasher);
205 ty::Predicate::TypeOutlives(ref pred) => {
206 pred.hash_stable(hcx, hasher);
208 ty::Predicate::Projection(ref pred) => {
209 pred.hash_stable(hcx, hasher);
211 ty::Predicate::WellFormed(ty) => {
212 ty.hash_stable(hcx, hasher);
214 ty::Predicate::ObjectSafe(def_id) => {
215 def_id.hash_stable(hcx, hasher);
217 ty::Predicate::ClosureKind(def_id, closure_kind) => {
218 def_id.hash_stable(hcx, hasher);
219 closure_kind.hash_stable(hcx, hasher);
225 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::AdtFlags {
226 fn hash_stable<W: StableHasherResult>(&self,
227 _: &mut StableHashingContext<'a, 'tcx>,
228 hasher: &mut StableHasher<W>) {
229 std_hash::Hash::hash(self, hasher);
233 impl_stable_hash_for!(struct ty::VariantDef {
241 impl_stable_hash_for!(enum ty::VariantDiscr {
246 impl_stable_hash_for!(struct ty::FieldDef {
252 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>>
253 for ::middle::const_val::ConstVal<'tcx> {
254 fn hash_stable<W: StableHasherResult>(&self,
255 hcx: &mut StableHashingContext<'a, 'tcx>,
256 hasher: &mut StableHasher<W>) {
257 use middle::const_val::ConstVal;
259 mem::discriminant(self).hash_stable(hcx, hasher);
262 ConstVal::Float(ref value) => {
263 value.hash_stable(hcx, hasher);
265 ConstVal::Integral(ref value) => {
266 value.hash_stable(hcx, hasher);
268 ConstVal::Str(ref value) => {
269 value.hash_stable(hcx, hasher);
271 ConstVal::ByteStr(ref value) => {
272 value.hash_stable(hcx, hasher);
274 ConstVal::Bool(value) => {
275 value.hash_stable(hcx, hasher);
277 ConstVal::Char(value) => {
278 value.hash_stable(hcx, hasher);
280 ConstVal::Variant(def_id) => {
281 def_id.hash_stable(hcx, hasher);
283 ConstVal::Function(def_id, substs) => {
284 def_id.hash_stable(hcx, hasher);
285 substs.hash_stable(hcx, hasher);
287 ConstVal::Struct(ref name_value_map) => {
288 let mut values: Vec<(InternedString, &ConstVal)> =
289 name_value_map.iter()
290 .map(|(name, val)| (name.as_str(), val))
293 values.sort_unstable_by_key(|&(ref name, _)| name.clone());
294 values.hash_stable(hcx, hasher);
296 ConstVal::Tuple(ref value) => {
297 value.hash_stable(hcx, hasher);
299 ConstVal::Array(ref value) => {
300 value.hash_stable(hcx, hasher);
302 ConstVal::Repeat(ref value, times) => {
303 value.hash_stable(hcx, hasher);
304 times.hash_stable(hcx, hasher);
310 impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
312 impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
317 impl_stable_hash_for!(enum ty::Variance {
324 impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
328 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Generics {
329 fn hash_stable<W: StableHasherResult>(&self,
330 hcx: &mut StableHashingContext<'a, 'tcx>,
331 hasher: &mut StableHasher<W>) {
339 // Reverse map to each `TypeParameterDef`'s `index` field, from
340 // `def_id.index` (`def_id.krate` is the same as the item's).
341 type_param_to_index: _, // Don't hash this
345 parent.hash_stable(hcx, hasher);
346 parent_regions.hash_stable(hcx, hasher);
347 parent_types.hash_stable(hcx, hasher);
348 regions.hash_stable(hcx, hasher);
349 types.hash_stable(hcx, hasher);
350 has_self.hash_stable(hcx, hasher);
354 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionParameterDef {
355 fn hash_stable<W: StableHasherResult>(&self,
356 hcx: &mut StableHashingContext<'a, 'tcx>,
357 hasher: &mut StableHasher<W>) {
358 let ty::RegionParameterDef {
366 name.hash_stable(hcx, hasher);
367 def_id.hash_stable(hcx, hasher);
368 index.hash_stable(hcx, hasher);
369 pure_wrt_drop.hash_stable(hcx, hasher);
373 impl_stable_hash_for!(struct ty::TypeParameterDef {
378 object_lifetime_default,
383 impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>>
384 for ::middle::resolve_lifetime::Set1<T>
385 where T: HashStable<StableHashingContext<'a, 'tcx>>
387 fn hash_stable<W: StableHasherResult>(&self,
388 hcx: &mut StableHashingContext<'a, 'tcx>,
389 hasher: &mut StableHasher<W>) {
390 use middle::resolve_lifetime::Set1;
392 mem::discriminant(self).hash_stable(hcx, hasher);
398 Set1::One(ref value) => {
399 value.hash_stable(hcx, hasher);
405 impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
407 EarlyBound(index, decl),
408 LateBound(db_index, decl),
409 LateBoundAnon(db_index, anon_index),
410 Free(call_site_scope_data, decl)
413 impl_stable_hash_for!(struct ty::DebruijnIndex {
417 impl_stable_hash_for!(enum ty::cast::CastKind {
431 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::middle::region::CodeExtent
433 fn hash_stable<W: StableHasherResult>(&self,
434 hcx: &mut StableHashingContext<'a, 'tcx>,
435 hasher: &mut StableHasher<W>) {
436 use middle::region::CodeExtent;
438 mem::discriminant(self).hash_stable(hcx, hasher);
440 CodeExtent::Misc(node_id) |
441 CodeExtent::DestructionScope(node_id) => {
442 node_id.hash_stable(hcx, hasher);
444 CodeExtent::CallSiteScope(body_id) |
445 CodeExtent::ParameterScope(body_id) => {
446 body_id.hash_stable(hcx, hasher);
448 CodeExtent::Remainder(block_remainder) => {
449 block_remainder.hash_stable(hcx, hasher);
455 impl_stable_hash_for!(struct ::middle::region::BlockRemainder {
457 first_statement_index
460 impl_stable_hash_for!(struct ty::adjustment::CoerceUnsizedInfo {
464 impl_stable_hash_for!(struct ty::FreeRegion {
469 impl_stable_hash_for!(enum ty::BoundRegion {
471 BrNamed(def_id, name),
476 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeVariants<'tcx>
478 fn hash_stable<W: StableHasherResult>(&self,
479 hcx: &mut StableHashingContext<'a, 'tcx>,
480 hasher: &mut StableHasher<W>) {
481 use ty::TypeVariants::*;
483 mem::discriminant(self).hash_stable(hcx, hasher);
489 // Nothing more to hash.
492 int_ty.hash_stable(hcx, hasher);
495 uint_ty.hash_stable(hcx, hasher);
497 TyFloat(float_ty) => {
498 float_ty.hash_stable(hcx, hasher);
500 TyAdt(adt_def, substs) => {
501 adt_def.hash_stable(hcx, hasher);
502 substs.hash_stable(hcx, hasher);
504 TyArray(inner_ty, len) => {
505 inner_ty.hash_stable(hcx, hasher);
506 len.hash_stable(hcx, hasher);
508 TySlice(inner_ty) => {
509 inner_ty.hash_stable(hcx, hasher);
511 TyRawPtr(pointee_ty) => {
512 pointee_ty.hash_stable(hcx, hasher);
514 TyRef(region, pointee_ty) => {
515 region.hash_stable(hcx, hasher);
516 pointee_ty.hash_stable(hcx, hasher);
518 TyFnDef(def_id, substs, ref sig) => {
519 def_id.hash_stable(hcx, hasher);
520 substs.hash_stable(hcx, hasher);
521 sig.hash_stable(hcx, hasher);
523 TyFnPtr(ref sig) => {
524 sig.hash_stable(hcx, hasher);
526 TyDynamic(ref existential_predicates, region) => {
527 existential_predicates.hash_stable(hcx, hasher);
528 region.hash_stable(hcx, hasher);
530 TyClosure(def_id, closure_substs) => {
531 def_id.hash_stable(hcx, hasher);
532 closure_substs.hash_stable(hcx, hasher);
534 TyTuple(inner_tys, from_diverging_type_var) => {
535 inner_tys.hash_stable(hcx, hasher);
536 from_diverging_type_var.hash_stable(hcx, hasher);
538 TyProjection(ref projection_ty) => {
539 projection_ty.hash_stable(hcx, hasher);
541 TyAnon(def_id, substs) => {
542 def_id.hash_stable(hcx, hasher);
543 substs.hash_stable(hcx, hasher);
545 TyParam(param_ty) => {
546 param_ty.hash_stable(hcx, hasher);
551 bug!("ty::TypeVariants::hash_stable() - Unexpected variant.")
557 impl_stable_hash_for!(struct ty::ParamTy {
562 impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> {
567 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::ExistentialPredicate<'tcx>
569 fn hash_stable<W: StableHasherResult>(&self,
570 hcx: &mut StableHashingContext<'a, 'tcx>,
571 hasher: &mut StableHasher<W>) {
572 mem::discriminant(self).hash_stable(hcx, hasher);
574 ty::ExistentialPredicate::Trait(ref trait_ref) => {
575 trait_ref.hash_stable(hcx, hasher);
577 ty::ExistentialPredicate::Projection(ref projection) => {
578 projection.hash_stable(hcx, hasher);
580 ty::ExistentialPredicate::AutoTrait(def_id) => {
581 def_id.hash_stable(hcx, hasher);
587 impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
592 impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
599 impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::TypeckTables<'tcx> {
600 fn hash_stable<W: StableHasherResult>(&self,
601 hcx: &mut StableHashingContext<'a, 'tcx>,
602 hasher: &mut StableHasher<W>) {
603 let ty::TypeckTables {
604 ref type_relative_path_defs,
609 ref upvar_capture_map,
612 ref liberated_fn_sigs,
617 // FIXME(#41184): This is still ignored at the moment.
619 ref used_trait_imports,
624 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
625 ich::hash_stable_nodemap(hcx, hasher, type_relative_path_defs);
626 ich::hash_stable_nodemap(hcx, hasher, node_types);
627 ich::hash_stable_nodemap(hcx, hasher, item_substs);
628 ich::hash_stable_nodemap(hcx, hasher, adjustments);
630 ich::hash_stable_hashmap(hcx, hasher, method_map, |hcx, method_call| {
636 let def_id = hcx.tcx().hir.local_def_id(expr_id);
637 (hcx.def_path_hash(def_id), autoderef)
640 ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| {
646 let var_def_id = hcx.tcx().hir.local_def_id(var_id);
647 let closure_def_id = hcx.tcx().hir.local_def_id(closure_expr_id);
648 (hcx.def_path_hash(var_def_id), hcx.def_path_hash(closure_def_id))
651 ich::hash_stable_nodemap(hcx, hasher, closure_tys);
652 ich::hash_stable_nodemap(hcx, hasher, closure_kinds);
653 ich::hash_stable_nodemap(hcx, hasher, liberated_fn_sigs);
654 ich::hash_stable_nodemap(hcx, hasher, fru_field_types);
655 ich::hash_stable_nodemap(hcx, hasher, cast_kinds);
657 ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| {
658 hcx.def_path_hash(*def_id)
661 tainted_by_errors.hash_stable(hcx, hasher);
662 free_region_map.hash_stable(hcx, hasher);