@@ -1196,8 +1196,6 @@ fn compare_projection_bounds<'tcx>(
1196
1196
return Ok ( ( ) ) ;
1197
1197
}
1198
1198
1199
- let param_env = tcx. param_env ( impl_ty. def_id ) ;
1200
-
1201
1199
// Given
1202
1200
//
1203
1201
// impl<A, B> Foo<u32> for (A, B) {
@@ -1212,6 +1210,36 @@ fn compare_projection_bounds<'tcx>(
1212
1210
impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
1213
1211
let impl_ty_value = tcx. type_of ( impl_ty. def_id ) ;
1214
1212
1213
+ let param_env = tcx. param_env ( impl_ty. def_id ) ;
1214
+
1215
+ // When checking something like
1216
+ //
1217
+ // trait X { type Y: PartialEq<<Self as X>::Y> }
1218
+ // impl X for T { default type Y = S; }
1219
+ //
1220
+ // We will have to prove the bound S: PartialEq<<T as X>::Y>. In this case
1221
+ // we want <T as X>::Y to normalize to S. This is valid because we are
1222
+ // checking the default value specifically here. Add this equality to the
1223
+ // ParamEnv for normalization specifically.
1224
+ let normalize_param_env = if impl_ty. defaultness . is_final ( ) {
1225
+ // If the associated type is final then normalization can already
1226
+ // do this without the explicit predicate.
1227
+ param_env
1228
+ } else {
1229
+ let mut predicates = param_env. caller_bounds ( ) . iter ( ) . collect :: < Vec < _ > > ( ) ;
1230
+ predicates. push (
1231
+ ty:: Binder :: dummy ( ty:: ProjectionPredicate {
1232
+ projection_ty : ty:: ProjectionTy {
1233
+ item_def_id : trait_ty. def_id ,
1234
+ substs : rebased_substs,
1235
+ } ,
1236
+ ty : impl_ty_value,
1237
+ } )
1238
+ . to_predicate ( tcx) ,
1239
+ ) ;
1240
+ ty:: ParamEnv :: new ( tcx. intern_predicates ( & predicates) , Reveal :: UserFacing , None )
1241
+ } ;
1242
+
1215
1243
// Map the predicate from the trait to the corresponding one for the impl.
1216
1244
// For example:
1217
1245
//
@@ -1275,9 +1303,11 @@ fn compare_projection_bounds<'tcx>(
1275
1303
_ => bug ! ( "unexepected projection predicate kind: `{:?}`" , predicate) ,
1276
1304
} ;
1277
1305
1306
+ debug ! ( "compare_projection_bounds: concrete predicate = {:?}" , concrete_ty_predicate) ;
1307
+
1278
1308
let traits:: Normalized { value : normalized_predicate, obligations } = traits:: normalize (
1279
1309
& mut selcx,
1280
- param_env ,
1310
+ normalize_param_env ,
1281
1311
normalize_cause. clone ( ) ,
1282
1312
& concrete_ty_predicate,
1283
1313
) ;
0 commit comments