From b46258f200e36217711a1ee4b4911238f9393a78 Mon Sep 17 00:00:00 2001 From: Jaime Valdemoros Date: Tue, 29 May 2018 11:23:38 +0200 Subject: [PATCH 1/4] Add hash_with method to TypeFoldable and define TypeHasher trait --- src/librustc/macros.rs | 32 ++++++++++ src/librustc/mir/interpret/value.rs | 4 ++ src/librustc/mir/mod.rs | 34 +++++++++- src/librustc/traits/structural_impls.rs | 22 ++++++- src/librustc/ty/fold.rs | 27 ++++++-- src/librustc/ty/structural_impls.rs | 82 ++++++++++++++++++++++++- src/librustc/ty/subst.rs | 13 +++- 7 files changed, 204 insertions(+), 10 deletions(-) diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index ccd9024f4aaab..2f0c735cf8eaa 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -205,6 +205,14 @@ macro_rules! CloneTypeFoldableImpls { { false } + + fn super_hash_with>( + &self, + _: &mut F) + -> u64 + { + unimplemented!() + } } )+ }; @@ -320,6 +328,14 @@ macro_rules! BraceStructTypeFoldableImpl { let $s { $($field,)* } = self; false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* } + + fn super_hash_with>( + &self, + _: &mut F) + -> u64 + { + unimplemented!() + } } }; } @@ -347,6 +363,14 @@ macro_rules! TupleStructTypeFoldableImpl { let $s($($field,)*) = self; false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* } + + fn super_hash_with>( + &self, + _: &mut F) + -> u64 + { + unimplemented!() + } } }; } @@ -372,6 +396,14 @@ macro_rules! EnumTypeFoldableImpl { ) -> bool { EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) } + + fn super_hash_with>( + &self, + _: &mut F) + -> u64 + { + unimplemented!() + } } }; diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 24595c9328208..b83a2487ddaa2 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -92,6 +92,10 @@ impl<'tcx> ty::TypeFoldable<'tcx> for Value { fn super_visit_with>(&self, _: &mut V) -> bool { false } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> Scalar { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 2198e3f6b318e..68f9329bad406 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -38,7 +38,7 @@ use std::{iter, mem, option, u32}; use syntax::ast::{self, Name}; use syntax::symbol::InternedString; use syntax_pos::{Span, DUMMY_SP}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use ty::fold::{TypeFoldable, TypeFolder, TypeHasher, TypeVisitor}; use ty::subst::{Subst, Substs}; use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt}; use util::ppaux; @@ -2681,6 +2681,10 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { | FalseUnwind { .. } => false, } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { @@ -2698,6 +2702,10 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { false } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { @@ -2764,6 +2772,10 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { } } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { @@ -2781,6 +2793,10 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { Operand::Constant(ref c) => c.visit_with(visitor), } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T> @@ -2812,6 +2828,10 @@ where _ => false, } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for Field { @@ -2821,6 +2841,10 @@ impl<'tcx> TypeFoldable<'tcx> for Field { fn super_visit_with>(&self, _: &mut V) -> bool { false } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { @@ -2834,6 +2858,10 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.ty.visit_with(visitor) || self.literal.visit_with(visitor) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> { @@ -2851,4 +2879,8 @@ impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> { Literal::Promoted { .. } => false, } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 39e358803cbe8..9c6c97e66daf8 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -12,7 +12,7 @@ use chalk_engine; use rustc_data_structures::accumulate_vec::AccumulateVec; use traits; use traits::project::Normalized; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use ty::fold::{TypeFoldable, TypeFolder, TypeHasher, TypeVisitor}; use ty::{self, Lift, TyCtxt}; use std::fmt; @@ -342,6 +342,10 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx fn super_visit_with>(&self, visitor: &mut V) -> bool { self.predicate.visit_with(visitor) } + + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.predicate.hash_with(hasher) + } } BraceStructTypeFoldableImpl! { @@ -630,6 +634,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for &'tcx traits::Goal<'tcx> { @@ -641,6 +649,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx traits::Goal<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { (**self).visit_with(visitor) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } BraceStructTypeFoldableImpl! { @@ -668,6 +680,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::ExClause @@ -689,6 +705,10 @@ where visitor, ) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx, C> Lift<'tcx> for chalk_engine::ExClause diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index f55a512908499..5a9e6229a5a25 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -63,12 +63,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.super_visit_with(visitor) } - /// True if `self` has any late-bound regions that are either - /// bound by `binder` or bound by some binder outside of `binder`. - /// If `binder` is `ty::INNERMOST`, this indicates whether - /// there are any late-bound regions that appear free. - fn has_regions_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool { - self.visit_with(&mut HasEscapingRegionsVisitor { outer_index: binder }) + fn super_hash_with>(&self, hasher: &mut H) -> u64; + fn hash_with>(&self, hasher: &mut H) -> u64 { + self.super_hash_with(hasher) } /// True if this `self` has any regions that escape `binder` (and @@ -197,6 +194,24 @@ pub trait TypeVisitor<'tcx> : Sized { } } +pub trait TypeHasher<'tcx> : Sized { + fn hash_binder>(&mut self, t: &Binder) -> u64 { + t.super_hash_with(self) + } + + fn hash_ty(&mut self, t: Ty<'tcx>) -> u64 { + t.super_hash_with(self) + } + + fn hash_region(&mut self, r: ty::Region<'tcx>) -> u64 { + r.super_hash_with(self) + } + + fn hash_const(&mut self, c: &'tcx ty::Const<'tcx>) -> u64 { + c.super_hash_with(self) + } +} + /////////////////////////////////////////////////////////////////////////// // Some sample folders diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index a648dc6e7e788..68d54ace1482e 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -15,7 +15,7 @@ use mir::interpret::{ConstValue, ConstEvalErr}; use ty::{self, Lift, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use ty::fold::{TypeFoldable, TypeFolder, TypeHasher, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use mir::interpret; @@ -660,6 +660,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { fn super_visit_with>(&self, _visitor: &mut V) -> bool { false } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { @@ -670,6 +674,10 @@ impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T fn super_visit_with>(&self, visitor: &mut V) -> bool { self.0.visit_with(visitor) || self.1.visit_with(visitor) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } EnumTypeFoldableImpl! { @@ -687,6 +695,10 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { fn super_visit_with>(&self, visitor: &mut V) -> bool { (**self).visit_with(visitor) } + + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + (**self).hash_with(hasher) + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { @@ -698,6 +710,10 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box { fn super_visit_with>(&self, visitor: &mut V) -> bool { (**self).visit_with(visitor) } + + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + (**self).hash_with(hasher) + } } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { @@ -708,6 +724,10 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { @@ -726,6 +746,14 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { fn visit_with>(&self, visitor: &mut V) -> bool { visitor.visit_binder(self) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } + + fn hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_binder(self) + } } BraceStructTypeFoldableImpl! { @@ -741,6 +769,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|p| p.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } EnumTypeFoldableImpl! { @@ -760,6 +792,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { @@ -815,6 +851,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { }, } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { @@ -828,6 +868,10 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.instance.visit_with(visitor) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { @@ -901,6 +945,14 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn visit_with>(&self, visitor: &mut V) -> bool { visitor.visit_ty(self) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } + + fn hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_ty(self) + } } BraceStructTypeFoldableImpl! { @@ -954,6 +1006,14 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { fn visit_with>(&self, visitor: &mut V) -> bool { visitor.visit_region(*self) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } + + fn hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_region(*self) + } } BraceStructTypeFoldableImpl! { @@ -1016,6 +1076,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|p| p.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } EnumTypeFoldableImpl! { @@ -1100,6 +1164,10 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } EnumTypeFoldableImpl! { @@ -1147,6 +1215,10 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor), } } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { @@ -1170,4 +1242,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { fn visit_with>(&self, visitor: &mut V) -> bool { visitor.visit_const(self) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } + + fn hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_const(self) + } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 2e3c6df9754df..269e055abfd64 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -12,7 +12,7 @@ use hir::def_id::DefId; use ty::{self, Lift, Slice, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use ty::fold::{TypeFoldable, TypeFolder, TypeHasher, TypeVisitor}; use serialize::{self, Encodable, Encoder, Decodable, Decoder}; use syntax_pos::{Span, DUMMY_SP}; @@ -162,6 +162,13 @@ impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> { UnpackedKind::Type(ty) => ty.visit_with(visitor), } } + + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + match self.unpack() { + UnpackedKind::Lifetime(lt) => lt.hash_with(hasher), + UnpackedKind::Type(ty) => ty.hash_with(hasher), + } + } } impl<'tcx> Encodable for Kind<'tcx> { @@ -338,6 +345,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { self.iter().any(|t| t.visit_with(visitor)) } + + fn super_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() + } } impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {} From 0c618abc9aa4082cadb03826077181815137dc8a Mon Sep 17 00:00:00 2001 From: Jaime Valdemoros Date: Tue, 29 May 2018 14:25:38 +0200 Subject: [PATCH 2/4] Implement a bunch of super_hash_with --- src/librustc/macros.rs | 76 ++++++++++++-- src/librustc/traits/mod.rs | 7 +- src/librustc/traits/structural_impls.rs | 7 +- src/librustc/ty/fold.rs | 9 +- src/librustc/ty/structural_impls.rs | 125 +++++++++++++++++++----- src/librustc/ty/subst.rs | 5 +- src/librustc_traits/chalk_context.rs | 19 +++- 7 files changed, 206 insertions(+), 42 deletions(-) diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index 2f0c735cf8eaa..f9a5b62e6afee 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -329,12 +329,14 @@ macro_rules! BraceStructTypeFoldableImpl { false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* } - fn super_hash_with>( + fn super_hash_with>( &self, - _: &mut F) + hasher: &mut H) -> u64 { - unimplemented!() + let $s { $($field,)* } = self; + $($crate::ty::fold::TypeFoldable::hash_with($field, hasher);)* + hasher.get_hash() } } }; @@ -364,12 +366,14 @@ macro_rules! TupleStructTypeFoldableImpl { false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* } - fn super_hash_with>( + fn super_hash_with>( &self, - _: &mut F) + hasher: &mut H) -> u64 { - unimplemented!() + let $s($($field,)*) = self; + $($crate::ty::fold::TypeFoldable::hash_with($field, hasher);)* + hasher.get_hash() } } }; @@ -397,12 +401,13 @@ macro_rules! EnumTypeFoldableImpl { EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) } - fn super_hash_with>( + fn super_hash_with>( &self, - _: &mut F) + hasher: &mut H) -> u64 { - unimplemented!() + EnumTypeFoldableImpl!(@HashVariants(self, hasher) input($($variants)*) output()); + hasher.get_hash() } } }; @@ -513,5 +518,58 @@ macro_rules! EnumTypeFoldableImpl { ) ) }; + + (@HashVariants($this:expr, $hasher:expr) input() output($($output:tt)*)) => { + match $this { + $($output)* + } + }; + + (@HashVariants($this:expr, $hasher:expr) + input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @HashVariants($this, $hasher) + input($($input)*) + output( + $variant ( $($variant_arg),* ) => { + $($crate::ty::fold::TypeFoldable::hash_with( + $variant_arg, $hasher + );)* + } + $($output)* + ) + ) + }; + + (@HashVariants($this:expr, $hasher:expr) + input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @HashVariants($this, $hasher) + input($($input)*) + output( + $variant { $($variant_arg),* } => { + $($crate::ty::fold::TypeFoldable::hash_with( + $variant_arg, $hasher + );)* + } + $($output)* + ) + ) + }; + + (@HashVariants($this:expr, $hasher:expr) + input( ($variant:path), $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @HashVariants($this, $hasher) + input($($input)*) + output( + $variant => { } + $($output)* + ) + ) + }; } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 0290f2e3b13f0..e7731decb8eb6 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -26,7 +26,7 @@ use mir::interpret::ConstEvalErr; use ty::subst::Substs; use ty::{self, AdtKind, Slice, Ty, TyCtxt, GenericParamDefKind, ToPredicate}; use ty::error::{ExpectedFound, TypeError}; -use ty::fold::{TypeFolder, TypeFoldable, TypeVisitor}; +use ty::fold::{TypeFolder, TypeFoldable, TypeHasher, TypeVisitor}; use infer::{InferCtxt}; use rustc_data_structures::sync::Lrc; @@ -1027,6 +1027,11 @@ where ex_clause: &chalk_engine::ExClause, visitor: &mut V, ) -> bool; + + fn hash_ex_clause_with<'gcx: 'tcx, H: TypeHasher<'tcx>>( + ex_clause: &chalk_engine::ExClause, + hasher: &mut H, + ) -> u64; } pub trait ExClauseLift<'tcx> diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 9c6c97e66daf8..99af7689a892c 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -706,8 +706,11 @@ where ) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + ::hash_ex_clause_with( + self, + hasher, + ) } } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 5a9e6229a5a25..9802d45f9295f 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -194,7 +194,7 @@ pub trait TypeVisitor<'tcx> : Sized { } } -pub trait TypeHasher<'tcx> : Sized { +pub trait TypeHasher<'tcx> : Sized + ::std::hash::Hasher { fn hash_binder>(&mut self, t: &Binder) -> u64 { t.super_hash_with(self) } @@ -210,6 +210,13 @@ pub trait TypeHasher<'tcx> : Sized { fn hash_const(&mut self, c: &'tcx ty::Const<'tcx>) -> u64 { c.super_hash_with(self) } + + fn hash_hashable(&mut self, h: H) -> u64 { + h.hash(self); + self.get_hash() + } + + fn get_hash(&self) -> u64; } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 68d54ace1482e..02b1ea94218ed 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -661,8 +661,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { false } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_hashable(self) } } @@ -675,8 +675,10 @@ impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T self.0.visit_with(visitor) || self.1.visit_with(visitor) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.0.hash_with(hasher); + self.1.hash_with(hasher); + hasher.get_hash() } } @@ -725,8 +727,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec { self.iter().any(|t| t.visit_with(visitor)) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() } } @@ -747,8 +750,8 @@ impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { visitor.visit_binder(self) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.skip_binder().hash_with(hasher) } fn hash_with>(&self, hasher: &mut H) -> u64 { @@ -770,8 +773,9 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice self.iter().any(|p| p.visit_with(visitor)) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.iter().for_each(|p| {p.hash_with(hasher);}); + hasher.get_hash() } } @@ -793,8 +797,9 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { self.iter().any(|t| t.visit_with(visitor)) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() } } @@ -852,8 +857,34 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { } } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + use ty::InstanceDef::*; + self.substs.hash_with(hasher); + match self.def { + Item(did) => did.hash_with(hasher), + Intrinsic(did) => did.hash_with(hasher), + FnPtrShim(did, ty) => { + did.hash_with(hasher); + ty.hash_with(hasher); + hasher.get_hash() + }, + Virtual(did, idx) => { + did.hash_with(hasher); + hasher.hash_hashable(idx); + hasher.get_hash() + } + ClosureOnceShim { call_once } => hasher.hash_hashable(call_once), + DropGlue(did, ty) => { + did.hash_with(hasher); + ty.hash_with(hasher); + hasher.get_hash() + }, + CloneShim(did, ty) => { + did.hash_with(hasher); + ty.hash_with(hasher); + hasher.get_hash() + }, + } } } @@ -869,8 +900,10 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { self.instance.visit_with(visitor) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.instance.hash_with(hasher); + hasher.hash_hashable(self.promoted); + hasher.get_hash() } } @@ -946,8 +979,44 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { visitor.visit_ty(self) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_hashable(self.region_depth); + hasher.hash_hashable(self.flags); + match self.sty { + ty::TyRawPtr(ref tm) => { tm.hash_with(hasher); } + ty::TyArray(typ, sz) => { + typ.hash_with(hasher); + sz.hash_with(hasher); + } + ty::TySlice(typ) => { typ.hash_with(hasher); } + ty::TyAdt(adt_def, substs) => { hasher.hash_hashable(adt_def); substs.hash_with(hasher); } + ty::TyDynamic(ref trait_ty, ref reg) => + { + trait_ty.hash_with(hasher); + reg.hash_with(hasher); + } + ty::TyTuple(ts) => { ts.hash_with(hasher); } + ty::TyFnDef(did, substs) => { hasher.hash_hashable(did); substs.hash_with(hasher); } + ty::TyFnPtr(ref f) => { f.hash_with(hasher); } + ty::TyRef(r, ty, mutability) => { + r.hash_with(hasher); + ty.hash_with(hasher); + hasher.hash_hashable(mutability); + } + ty::TyGenerator(did, ref substs, mov) => { + hasher.hash_hashable(did); + substs.hash_with(hasher); + hasher.hash_hashable(mov); + } + ty::TyGeneratorWitness(ref types) => { types.hash_with(hasher); } + ty::TyClosure(_did, ref substs) => { substs.hash_with(hasher); } + ty::TyProjection(ref data) => { data.hash_with(hasher); } + ty::TyAnon(_, ref substs) => { substs.hash_with(hasher); } + ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) | + ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) | + ty::TyParam(..) | ty::TyNever | ty::TyForeign(..) => { hasher.hash_hashable(&self.sty); } + }; + hasher.get_hash() } fn hash_with>(&self, hasher: &mut H) -> u64 { @@ -1077,8 +1146,9 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { self.iter().any(|p| p.visit_with(visitor)) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.iter().for_each(|p| {p.hash_with(hasher);}); + hasher.get_hash() } } @@ -1165,8 +1235,9 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec self.iter().any(|t| t.visit_with(visitor)) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() } } @@ -1216,8 +1287,8 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { } } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_hashable(self) } } @@ -1243,8 +1314,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { visitor.visit_const(self) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.ty.hash_with(hasher); + self.val.hash_with(hasher); + hasher.get_hash() } fn hash_with>(&self, hasher: &mut H) -> u64 { diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 269e055abfd64..56b1a7714d315 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -346,8 +346,9 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx Substs<'tcx> { self.iter().any(|t| t.visit_with(visitor)) } - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() } } diff --git a/src/librustc_traits/chalk_context.rs b/src/librustc_traits/chalk_context.rs index 6062fe03e6a16..5ebfb150b4fa5 100644 --- a/src/librustc_traits/chalk_context.rs +++ b/src/librustc_traits/chalk_context.rs @@ -22,7 +22,7 @@ use rustc::traits::{ ProgramClause, QuantifierKind }; -use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeHasher, TypeVisitor}; use rustc::ty::subst::Kind; use rustc::ty::{self, TyCtxt}; @@ -508,6 +508,23 @@ impl ExClauseFold<'tcx> for ChalkArenas<'tcx> { && constraints.visit_with(visitor) && subgoals.visit_with(visitor) } + + fn hash_ex_clause_with<'gcx: 'tcx, H: TypeHasher<'tcx>>( + ex_clause: &ExClause, + hasher: &mut H, + ) -> u64 { + let ExClause { + subst, + delayed_literals, + constraints, + subgoals, + } = ex_clause; + subst.hash_with(hasher); + delayed_literals.hash_with(hasher); + constraints.hash_with(hasher); + subgoals.hash_with(hasher); + hasher.get_hash() + } } BraceStructLiftImpl! { From 5e302e87eab489fcc899d4fbbbf0b51e1734c000 Mon Sep 17 00:00:00 2001 From: Jaime Valdemoros Date: Fri, 29 Jun 2018 08:49:10 +0100 Subject: [PATCH 3/4] Use the TypeFoldable macros for Operand and Field --- src/librustc/mir/mod.rs | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 68f9329bad406..e098f01eada21 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2778,24 +2778,11 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - Operand::Copy(ref place) => Operand::Copy(place.fold_with(folder)), - Operand::Move(ref place) => Operand::Move(place.fold_with(folder)), - Operand::Constant(ref c) => Operand::Constant(c.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor), - Operand::Constant(ref c) => c.visit_with(visitor), - } - } - - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { + (Operand::Copy)(place), + (Operand::Move)(place), + (Operand::Constant)(c), } } @@ -2834,17 +2821,8 @@ where } } -impl<'tcx> TypeFoldable<'tcx> for Field { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> Self { - *self - } - fn super_visit_with>(&self, _: &mut V) -> bool { - false - } - - fn super_hash_with>(&self, _hasher: &mut H) -> u64 { - unimplemented!() - } +TupleStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for Field {} } impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { From d4c414fad5f6f70cdc4721e8396807aced450ccc Mon Sep 17 00:00:00 2001 From: Jaime Valdemoros Date: Fri, 29 Jun 2018 09:09:10 +0100 Subject: [PATCH 4/4] Hash the discriminant in super_hash_with for enums --- src/librustc/macros.rs | 1 + src/librustc/ty/structural_impls.rs | 3 +++ src/librustc/ty/subst.rs | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index f9a5b62e6afee..67f5a78233010 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -520,6 +520,7 @@ macro_rules! EnumTypeFoldableImpl { }; (@HashVariants($this:expr, $hasher:expr) input() output($($output:tt)*)) => { + ::std::mem::discriminant($this).hash($hasher); match $this { $($output)* } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 02b1ea94218ed..b8977db00550b 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -20,6 +20,7 @@ use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use mir::interpret; +use std::mem; use std::rc::Rc; /////////////////////////////////////////////////////////////////////////// @@ -860,6 +861,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { fn super_hash_with>(&self, hasher: &mut H) -> u64 { use ty::InstanceDef::*; self.substs.hash_with(hasher); + mem::discriminant(&self.def).hash(hasher); match self.def { Item(did) => did.hash_with(hasher), Intrinsic(did) => did.hash_with(hasher), @@ -982,6 +984,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn super_hash_with>(&self, hasher: &mut H) -> u64 { hasher.hash_hashable(self.region_depth); hasher.hash_hashable(self.flags); + mem::discriminant(&self.sty).hash(hasher); match self.sty { ty::TyRawPtr(ref tm) => { tm.hash_with(hasher); } ty::TyArray(typ, sz) => { diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 56b1a7714d315..cc40f726a0f93 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -164,7 +164,9 @@ impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> { } fn super_hash_with>(&self, hasher: &mut H) -> u64 { - match self.unpack() { + let unpacked = self.unpack(); + mem::discriminant(&unpacked).hash(hasher); + match unpacked { UnpackedKind::Lifetime(lt) => lt.hash_with(hasher), UnpackedKind::Type(ty) => ty.hash_with(hasher), }