diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-01-01 13:15:14 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-01-01 18:48:26 -0500 |
| commit | 7092af7ee317a42c8ad7d9f8d02bb9ff64891949 (patch) | |
| tree | 030c23ecbf3d5d3f9bb0860266740ecbac5f3b70 | |
| parent | 39d74026663597a8d4ad0ab04e6d117bf9fd6ad4 (diff) | |
| download | rust-7092af7ee317a42c8ad7d9f8d02bb9ff64891949.tar.gz rust-7092af7ee317a42c8ad7d9f8d02bb9ff64891949.zip | |
Normalize predicates found on the impl
| -rw-r--r-- | src/librustc/middle/traits/project.rs | 38 | ||||
| -rw-r--r-- | src/librustc/middle/traits/select.rs | 20 |
2 files changed, 49 insertions, 9 deletions
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index 28a826b859b..c84f31bf6c3 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -102,7 +102,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>( /// Compute result of projecting an associated type and unify it with /// `obligation.predicate.ty` (if we can). -pub fn project_and_unify_type<'cx,'tcx>( +fn project_and_unify_type<'cx,'tcx>( selcx: &mut SelectionContext<'cx,'tcx>, obligation: &ProjectionObligation<'tcx>) -> Result<Option<Vec<PredicateObligation<'tcx>>>, MismatchedProjectionTypes<'tcx>> @@ -135,9 +135,19 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>, cause: ObligationCause<'tcx>, value: &T) -> Normalized<'tcx, T> - where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx> { - let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, 0); + normalize_with_depth(selcx, cause, 0, value) +} + +pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>, + cause: ObligationCause<'tcx>, + depth: uint, + value: &T) + -> Normalized<'tcx, T> + where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx> +{ + let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth); let result = normalizer.fold(value); Normalized { value: result, @@ -278,9 +288,10 @@ fn opt_normalize_projection_type<'a,'b,'tcx>( // an impl, where-clause etc) and hence we must // re-normalize it - debug!("normalize_projection_type: projected_ty={} depth={}", + debug!("normalize_projection_type: projected_ty={} depth={} obligations={}", projected_ty.repr(selcx.tcx()), - depth); + depth, + obligations.repr(selcx.tcx())); if ty::type_has_projection(projected_ty) { let tcx = selcx.tcx(); @@ -644,3 +655,20 @@ impl<'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> { } } } + +impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> { + fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Normalized<'tcx, T> { + Normalized { + value: self.value.fold_with(folder), + obligations: self.obligations.fold_with(folder), + } + } +} + +impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Normalized<'tcx, T> { + fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { + format!("Normalized({},{})", + self.value.repr(tcx), + self.obligations.repr(tcx)) + } +} diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index ce5337a58e1..3837cb97228 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -18,6 +18,7 @@ use self::BuiltinBoundConditions::*; use self::EvaluationResult::*; use super::{DerivedObligationCause}; +use super::{project}; use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause}; use super::{ObligationCauseCode, BuiltinDerivedObligation}; use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch}; @@ -29,7 +30,7 @@ use super::{util}; use middle::fast_reject; use middle::mem_categorization::Typer; -use middle::subst::{Subst, Substs, VecPerParamSpace}; +use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace}; use middle::ty::{mod, AsPredicate, RegionEscape, ToPolyTraitRef, Ty}; use middle::infer; use middle::infer::{InferCtxt, TypeFreshener}; @@ -2100,7 +2101,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - fn impl_predicates(&self, + fn impl_predicates(&mut self, cause: ObligationCause<'tcx>, recursion_depth: uint, impl_def_id: ast::DefId, @@ -2111,8 +2112,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics; let bounds = impl_generics.to_bounds(self.tcx(), impl_substs); - let bounds = self.infcx().plug_leaks(skol_map, snapshot, &bounds); - util::predicates_for_generics(self.tcx(), cause, recursion_depth, &bounds) + let normalized_bounds = + project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds); + let normalized_bounds = + self.infcx().plug_leaks(skol_map, snapshot, &normalized_bounds); + let mut impl_obligations = + util::predicates_for_generics(self.tcx(), + cause, + recursion_depth, + &normalized_bounds.value); + for obligation in normalized_bounds.obligations.into_iter() { + impl_obligations.push(TypeSpace, obligation); + } + impl_obligations } fn fn_family_trait_kind(&self, |
