@@ -6,15 +6,14 @@ use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
66use rustc_infer:: infer:: { self , InferOk , TyCtxtInferExt } ;
77use rustc_middle:: ty;
88use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
9- use rustc_middle:: ty:: subst:: { InternalSubsts , Subst , SubstsRef } ;
9+ use rustc_middle:: ty:: subst:: { InternalSubsts , Subst } ;
1010use rustc_middle:: ty:: util:: ExplicitSelf ;
11- use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt , WithConstness } ;
11+ use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt } ;
1212use rustc_span:: Span ;
1313use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
1414use rustc_trait_selection:: traits:: { self , ObligationCause , ObligationCauseCode , Reveal } ;
1515
1616use super :: { potentially_plural_count, FnCtxt , Inherited } ;
17- use std:: iter;
1817
1918/// Checks that a method from an impl conforms to the signature of
2019/// the same method as declared in the trait.
@@ -1196,8 +1195,6 @@ fn compare_projection_bounds<'tcx>(
11961195 return Ok ( ( ) ) ;
11971196 }
11981197
1199- let param_env = tcx. param_env ( impl_ty. def_id ) ;
1200-
12011198 // Given
12021199 //
12031200 // impl<A, B> Foo<u32> for (A, B) {
@@ -1212,20 +1209,30 @@ fn compare_projection_bounds<'tcx>(
12121209 impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
12131210 let impl_ty_value = tcx. type_of ( impl_ty. def_id ) ;
12141211
1215- // Map the predicate from the trait to the corresponding one for the impl.
1216- // For example:
1212+ let param_env = tcx. param_env ( impl_ty. def_id ) ;
1213+
1214+ // When checking something like
12171215 //
1218- // trait X<A> { type Y<'a> : PartialEq<A> } impl X for T { type Y<'a> = &'a S; }
1219- // impl<'x> X<&'x u32> for () { type Y<'c> = &'c u32 ; }
1216+ // trait X { type Y: PartialEq<<Self as X>::Y> }
1217+ // impl X for T { default type Y = S ; }
12201218 //
1221- // For the `for<'a> <<Self as X<A>>::Y<'a>: PartialEq<A>` bound, this
1222- // function would translate and partially normalize
1223- // `[<Self as X<A>>::Y<'a>, A]` to `[&'a u32, &'x u32]`.
1224- let translate_predicate_substs = move |predicate_substs : SubstsRef < ' tcx > | {
1225- tcx. mk_substs (
1226- iter:: once ( impl_ty_value. into ( ) )
1227- . chain ( predicate_substs[ 1 ..] . iter ( ) . map ( |s| s. subst ( tcx, rebased_substs) ) ) ,
1228- )
1219+ // We will have to prove the bound S: PartialEq<<T as X>::Y>. In this case
1220+ // we want <T as X>::Y to normalize to S. This is valid because we are
1221+ // checking the default value specifically here. Add this equality to the
1222+ // ParamEnv for normalization specifically.
1223+ let normalize_param_env = {
1224+ let mut predicates = param_env. caller_bounds ( ) . iter ( ) . collect :: < Vec < _ > > ( ) ;
1225+ predicates. push (
1226+ ty:: Binder :: dummy ( ty:: ProjectionPredicate {
1227+ projection_ty : ty:: ProjectionTy {
1228+ item_def_id : trait_ty. def_id ,
1229+ substs : rebased_substs,
1230+ } ,
1231+ ty : impl_ty_value,
1232+ } )
1233+ . to_predicate ( tcx) ,
1234+ ) ;
1235+ ty:: ParamEnv :: new ( tcx. intern_predicates ( & predicates) , Reveal :: UserFacing , None )
12291236 } ;
12301237
12311238 tcx. infer_ctxt ( ) . enter ( move |infcx| {
@@ -1242,46 +1249,18 @@ fn compare_projection_bounds<'tcx>(
12421249 ) ;
12431250
12441251 let predicates = tcx. projection_predicates ( trait_ty. def_id ) ;
1245-
12461252 debug ! ( "compare_projection_bounds: projection_predicates={:?}" , predicates) ;
12471253
12481254 for predicate in predicates {
1249- let concrete_ty_predicate = match predicate. kind ( ) {
1250- ty:: PredicateKind :: Trait ( poly_tr, c) => poly_tr
1251- . map_bound ( |tr| {
1252- let trait_substs = translate_predicate_substs ( tr. trait_ref . substs ) ;
1253- ty:: TraitRef { def_id : tr. def_id ( ) , substs : trait_substs }
1254- } )
1255- . with_constness ( * c)
1256- . to_predicate ( tcx) ,
1257- ty:: PredicateKind :: Projection ( poly_projection) => poly_projection
1258- . map_bound ( |projection| {
1259- let projection_substs =
1260- translate_predicate_substs ( projection. projection_ty . substs ) ;
1261- ty:: ProjectionPredicate {
1262- projection_ty : ty:: ProjectionTy {
1263- substs : projection_substs,
1264- item_def_id : projection. projection_ty . item_def_id ,
1265- } ,
1266- ty : projection. ty . subst ( tcx, rebased_substs) ,
1267- }
1268- } )
1269- . to_predicate ( tcx) ,
1270- ty:: PredicateKind :: TypeOutlives ( poly_outlives) => poly_outlives
1271- . map_bound ( |outlives| {
1272- ty:: OutlivesPredicate ( impl_ty_value, outlives. 1 . subst ( tcx, rebased_substs) )
1273- } )
1274- . to_predicate ( tcx) ,
1275- _ => bug ! ( "unexepected projection predicate kind: `{:?}`" , predicate) ,
1276- } ;
1255+ let concrete_ty_predicate = predicate. subst ( tcx, rebased_substs) ;
1256+ debug ! ( "compare_projection_bounds: concrete predicate = {:?}" , concrete_ty_predicate) ;
12771257
12781258 let traits:: Normalized { value : normalized_predicate, obligations } = traits:: normalize (
12791259 & mut selcx,
1280- param_env ,
1260+ normalize_param_env ,
12811261 normalize_cause. clone ( ) ,
12821262 & concrete_ty_predicate,
12831263 ) ;
1284-
12851264 debug ! ( "compare_projection_bounds: normalized predicate = {:?}" , normalized_predicate) ;
12861265
12871266 inh. register_predicates ( obligations) ;
0 commit comments