diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index ccd9024f4aaab..67f5a78233010 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,16 @@ macro_rules! BraceStructTypeFoldableImpl { let $s { $($field,)* } = self; false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* } + + fn super_hash_with>( + &self, + hasher: &mut H) + -> u64 + { + let $s { $($field,)* } = self; + $($crate::ty::fold::TypeFoldable::hash_with($field, hasher);)* + hasher.get_hash() + } } }; } @@ -347,6 +365,16 @@ macro_rules! TupleStructTypeFoldableImpl { let $s($($field,)*) = self; false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* } + + fn super_hash_with>( + &self, + hasher: &mut H) + -> u64 + { + let $s($($field,)*) = self; + $($crate::ty::fold::TypeFoldable::hash_with($field, hasher);)* + hasher.get_hash() + } } }; } @@ -372,6 +400,15 @@ macro_rules! EnumTypeFoldableImpl { ) -> bool { EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) } + + fn super_hash_with>( + &self, + hasher: &mut H) + -> u64 + { + EnumTypeFoldableImpl!(@HashVariants(self, hasher) input($($variants)*) output()); + hasher.get_hash() + } } }; @@ -481,5 +518,59 @@ macro_rules! EnumTypeFoldableImpl { ) ) }; + + (@HashVariants($this:expr, $hasher:expr) input() output($($output:tt)*)) => { + ::std::mem::discriminant($this).hash($hasher); + 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/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..e098f01eada21 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,22 +2772,17 @@ 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_hash_with>(&self, _hasher: &mut H) -> u64 { + unimplemented!() } +} - 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), - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { + (Operand::Copy)(place), + (Operand::Move)(place), + (Operand::Constant)(c), } } @@ -2812,17 +2815,16 @@ where _ => false, } } -} -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> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { Constant { @@ -2834,6 +2836,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 +2857,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/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 39e358803cbe8..99af7689a892c 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,13 @@ where visitor, ) } + + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + ::hash_ex_clause_with( + self, + hasher, + ) + } } 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..9802d45f9295f 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,31 @@ pub trait TypeVisitor<'tcx> : Sized { } } +pub trait TypeHasher<'tcx> : Sized + ::std::hash::Hasher { + 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) + } + + fn hash_hashable(&mut self, h: H) -> u64 { + h.hash(self); + self.get_hash() + } + + fn get_hash(&self) -> u64; +} + /////////////////////////////////////////////////////////////////////////// // Some sample folders diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index a648dc6e7e788..b8977db00550b 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -15,11 +15,12 @@ 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; +use std::mem; use std::rc::Rc; /////////////////////////////////////////////////////////////////////////// @@ -660,6 +661,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 { + hasher.hash_hashable(self) + } } impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { @@ -670,6 +675,12 @@ 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 { + self.0.hash_with(hasher); + self.1.hash_with(hasher); + hasher.get_hash() + } } EnumTypeFoldableImpl! { @@ -687,6 +698,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 +713,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 +727,11 @@ 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 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() + } } impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder { @@ -726,6 +750,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 { + self.skip_binder().hash_with(hasher) + } + + fn hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_binder(self) + } } BraceStructTypeFoldableImpl! { @@ -741,6 +773,11 @@ 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 { + self.iter().for_each(|p| {p.hash_with(hasher);}); + hasher.get_hash() + } } EnumTypeFoldableImpl! { @@ -760,6 +797,11 @@ 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 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() + } } impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { @@ -815,6 +857,37 @@ 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), + 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() + }, + } + } } impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { @@ -828,6 +901,12 @@ 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 { + self.instance.hash_with(hasher); + hasher.hash_hashable(self.promoted); + hasher.get_hash() + } } impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { @@ -901,6 +980,51 @@ 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 { + 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) => { + 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 { + hasher.hash_ty(self) + } } BraceStructTypeFoldableImpl! { @@ -954,6 +1078,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 +1148,11 @@ 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 { + self.iter().for_each(|p| {p.hash_with(hasher);}); + hasher.get_hash() + } } EnumTypeFoldableImpl! { @@ -1100,6 +1237,11 @@ 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 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() + } } EnumTypeFoldableImpl! { @@ -1147,6 +1289,10 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor), } } + + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + hasher.hash_hashable(self) + } } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { @@ -1170,4 +1316,14 @@ 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 { + self.ty.hash_with(hasher); + self.val.hash_with(hasher); + hasher.get_hash() + } + + 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..cc40f726a0f93 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,15 @@ impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> { UnpackedKind::Type(ty) => ty.visit_with(visitor), } } + + fn super_hash_with>(&self, hasher: &mut H) -> u64 { + 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), + } + } } impl<'tcx> Encodable for Kind<'tcx> { @@ -338,6 +347,11 @@ 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 { + self.iter().for_each(|t| {t.hash_with(hasher);}); + hasher.get_hash() + } } impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {} 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! {