Skip to content

Commit 7092af7

Browse files
committed
Normalize predicates found on the impl
1 parent 39d7402 commit 7092af7

File tree

2 files changed

+49
-9
lines changed

2 files changed

+49
-9
lines changed

src/librustc/middle/traits/project.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(
102102

103103
/// Compute result of projecting an associated type and unify it with
104104
/// `obligation.predicate.ty` (if we can).
105-
pub fn project_and_unify_type<'cx,'tcx>(
105+
fn project_and_unify_type<'cx,'tcx>(
106106
selcx: &mut SelectionContext<'cx,'tcx>,
107107
obligation: &ProjectionObligation<'tcx>)
108108
-> Result<Option<Vec<PredicateObligation<'tcx>>>, MismatchedProjectionTypes<'tcx>>
@@ -135,9 +135,19 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
135135
cause: ObligationCause<'tcx>,
136136
value: &T)
137137
-> Normalized<'tcx, T>
138-
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone
138+
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
139139
{
140-
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, 0);
140+
normalize_with_depth(selcx, cause, 0, value)
141+
}
142+
143+
pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
144+
cause: ObligationCause<'tcx>,
145+
depth: uint,
146+
value: &T)
147+
-> Normalized<'tcx, T>
148+
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
149+
{
150+
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth);
141151
let result = normalizer.fold(value);
142152
Normalized {
143153
value: result,
@@ -278,9 +288,10 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
278288
// an impl, where-clause etc) and hence we must
279289
// re-normalize it
280290

281-
debug!("normalize_projection_type: projected_ty={} depth={}",
291+
debug!("normalize_projection_type: projected_ty={} depth={} obligations={}",
282292
projected_ty.repr(selcx.tcx()),
283-
depth);
293+
depth,
294+
obligations.repr(selcx.tcx()));
284295

285296
if ty::type_has_projection(projected_ty) {
286297
let tcx = selcx.tcx();
@@ -644,3 +655,20 @@ impl<'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> {
644655
}
645656
}
646657
}
658+
659+
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
660+
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Normalized<'tcx, T> {
661+
Normalized {
662+
value: self.value.fold_with(folder),
663+
obligations: self.obligations.fold_with(folder),
664+
}
665+
}
666+
}
667+
668+
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Normalized<'tcx, T> {
669+
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
670+
format!("Normalized({},{})",
671+
self.value.repr(tcx),
672+
self.obligations.repr(tcx))
673+
}
674+
}

src/librustc/middle/traits/select.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use self::BuiltinBoundConditions::*;
1818
use self::EvaluationResult::*;
1919

2020
use super::{DerivedObligationCause};
21+
use super::{project};
2122
use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause};
2223
use super::{ObligationCauseCode, BuiltinDerivedObligation};
2324
use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
@@ -29,7 +30,7 @@ use super::{util};
2930

3031
use middle::fast_reject;
3132
use middle::mem_categorization::Typer;
32-
use middle::subst::{Subst, Substs, VecPerParamSpace};
33+
use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
3334
use middle::ty::{mod, AsPredicate, RegionEscape, ToPolyTraitRef, Ty};
3435
use middle::infer;
3536
use middle::infer::{InferCtxt, TypeFreshener};
@@ -2100,7 +2101,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
21002101
}
21012102
}
21022103

2103-
fn impl_predicates(&self,
2104+
fn impl_predicates(&mut self,
21042105
cause: ObligationCause<'tcx>,
21052106
recursion_depth: uint,
21062107
impl_def_id: ast::DefId,
@@ -2111,8 +2112,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
21112112
{
21122113
let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
21132114
let bounds = impl_generics.to_bounds(self.tcx(), impl_substs);
2114-
let bounds = self.infcx().plug_leaks(skol_map, snapshot, &bounds);
2115-
util::predicates_for_generics(self.tcx(), cause, recursion_depth, &bounds)
2115+
let normalized_bounds =
2116+
project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds);
2117+
let normalized_bounds =
2118+
self.infcx().plug_leaks(skol_map, snapshot, &normalized_bounds);
2119+
let mut impl_obligations =
2120+
util::predicates_for_generics(self.tcx(),
2121+
cause,
2122+
recursion_depth,
2123+
&normalized_bounds.value);
2124+
for obligation in normalized_bounds.obligations.into_iter() {
2125+
impl_obligations.push(TypeSpace, obligation);
2126+
}
2127+
impl_obligations
21162128
}
21172129

21182130
fn fn_family_trait_kind(&self,

0 commit comments

Comments
 (0)