diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 1919d8ffd294..5f2f4df2f160 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -614,7 +614,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, snapshot: &CombinedSnapshot, value: &T) -> T - where T : TypeFoldable<'tcx> + where T : TypeFoldable<'tcx> + ty::HasTypeFlags { debug_assert!(leak_check(infcx, &skol_map, snapshot).is_ok()); diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 1b47ce75bc50..d56a73c36570 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -985,7 +985,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { snapshot: &CombinedSnapshot, value: &T) -> T - where T : TypeFoldable<'tcx> + where T : TypeFoldable<'tcx> + HasTypeFlags { /*! See `higher_ranked::plug_leaks` */ @@ -1256,7 +1256,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - pub fn resolve_type_vars_if_possible>(&self, value: &T) -> T { + pub fn resolve_type_vars_if_possible(&self, value: &T) -> T + where T: TypeFoldable<'tcx> + HasTypeFlags + { /*! * Where possible, replaces type/int/float variables in * `value` with their final value. Note that region variables @@ -1266,6 +1268,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { * at will. */ + if !value.needs_infer() { + return value.clone(); // avoid duplicated subst-folding + } let mut r = resolve::OpportunisticTypeResolver::new(self); value.fold_with(&mut r) } diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 467c752499b3..3be05c45c4de 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -160,7 +160,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, obligation: &Obligation<'tcx, T>) -> ! - where T: fmt::Display + TypeFoldable<'tcx> + where T: fmt::Display + TypeFoldable<'tcx> + HasTypeFlags { let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate); diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index ef3a217ecdbf..cacefbb1a855 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -927,6 +927,13 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> { } } +impl<'tcx, T: HasTypeFlags> HasTypeFlags for Normalized<'tcx, T> { + fn has_type_flags(&self, flags: ty::TypeFlags) -> bool { + self.value.has_type_flags(flags) || + self.obligations.has_type_flags(flags) + } +} + impl<'tcx, T:fmt::Debug> fmt::Debug for Normalized<'tcx, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Normalized({:?},{:?})", diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 9f5b24c6b765..f99760b6210c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -7280,6 +7280,24 @@ impl<'tcx,T:HasTypeFlags> HasTypeFlags for VecPerParamSpace { } } +impl HasTypeFlags for abi::Abi { + fn has_type_flags(&self, _flags: TypeFlags) -> bool { + false + } +} + +impl HasTypeFlags for ast::Unsafety { + fn has_type_flags(&self, _flags: TypeFlags) -> bool { + false + } +} + +impl HasTypeFlags for BuiltinBounds { + fn has_type_flags(&self, _flags: TypeFlags) -> bool { + false + } +} + impl<'tcx> HasTypeFlags for ClosureTy<'tcx> { fn has_type_flags(&self, flags: TypeFlags) -> bool { self.sig.has_type_flags(flags) @@ -7292,6 +7310,12 @@ impl<'tcx> HasTypeFlags for ClosureUpvar<'tcx> { } } +impl<'tcx> HasTypeFlags for ExistentialBounds<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.projection_bounds.has_type_flags(flags) + } +} + impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> { fn has_type_flags(&self, flags: TypeFlags) -> bool { self.predicates.has_type_flags(flags) @@ -7367,6 +7391,12 @@ impl<'tcx> HasTypeFlags for Ty<'tcx> { } } +impl<'tcx> HasTypeFlags for TypeAndMut<'tcx> { + fn has_type_flags(&self, flags: TypeFlags) -> bool { + self.ty.has_type_flags(flags) + } +} + impl<'tcx> HasTypeFlags for TraitRef<'tcx> { fn has_type_flags(&self, flags: TypeFlags) -> bool { self.substs.has_type_flags(flags) diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs index 05b08b356efd..f307f674732a 100644 --- a/src/librustc/middle/ty_relate/mod.rs +++ b/src/librustc/middle/ty_relate/mod.rs @@ -14,7 +14,7 @@ //! type equality, etc. use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs}; -use middle::ty::{self, Ty, TypeError}; +use middle::ty::{self, HasTypeFlags, Ty, TypeError}; use middle::ty_fold::TypeFoldable; use std::rc::Rc; use syntax::abi; @@ -78,7 +78,7 @@ pub trait TypeRelation<'a,'tcx> : Sized { where T: Relate<'a,'tcx>; } -pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> { +pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> + HasTypeFlags { fn relate>(relation: &mut R, a: &Self, b: &Self)