@@ -6,15 +6,14 @@ use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
6
6
use rustc_infer:: infer:: { self , InferOk , TyCtxtInferExt } ;
7
7
use rustc_middle:: ty;
8
8
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
9
- use rustc_middle:: ty:: subst:: { InternalSubsts , Subst , SubstsRef } ;
9
+ use rustc_middle:: ty:: subst:: { InternalSubsts , Subst } ;
10
10
use rustc_middle:: ty:: util:: ExplicitSelf ;
11
- use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt , WithConstness } ;
11
+ use rustc_middle:: ty:: { GenericParamDefKind , ToPredicate , TyCtxt } ;
12
12
use rustc_span:: Span ;
13
13
use rustc_trait_selection:: traits:: error_reporting:: InferCtxtExt ;
14
14
use rustc_trait_selection:: traits:: { self , ObligationCause , ObligationCauseCode , Reveal } ;
15
15
16
16
use super :: { potentially_plural_count, FnCtxt , Inherited } ;
17
- use std:: iter;
18
17
19
18
/// Checks that a method from an impl conforms to the signature of
20
19
/// the same method as declared in the trait.
@@ -1196,8 +1195,6 @@ fn compare_projection_bounds<'tcx>(
1196
1195
return Ok ( ( ) ) ;
1197
1196
}
1198
1197
1199
- let param_env = tcx. param_env ( impl_ty. def_id ) ;
1200
-
1201
1198
// Given
1202
1199
//
1203
1200
// impl<A, B> Foo<u32> for (A, B) {
@@ -1212,20 +1209,30 @@ fn compare_projection_bounds<'tcx>(
1212
1209
impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
1213
1210
let impl_ty_value = tcx. type_of ( impl_ty. def_id ) ;
1214
1211
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
1217
1215
//
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 ; }
1220
1218
//
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 )
1229
1236
} ;
1230
1237
1231
1238
tcx. infer_ctxt ( ) . enter ( move |infcx| {
@@ -1242,46 +1249,18 @@ fn compare_projection_bounds<'tcx>(
1242
1249
) ;
1243
1250
1244
1251
let predicates = tcx. projection_predicates ( trait_ty. def_id ) ;
1245
-
1246
1252
debug ! ( "compare_projection_bounds: projection_predicates={:?}" , predicates) ;
1247
1253
1248
1254
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) ;
1277
1257
1278
1258
let traits:: Normalized { value : normalized_predicate, obligations } = traits:: normalize (
1279
1259
& mut selcx,
1280
- param_env ,
1260
+ normalize_param_env ,
1281
1261
normalize_cause. clone ( ) ,
1282
1262
& concrete_ty_predicate,
1283
1263
) ;
1284
-
1285
1264
debug ! ( "compare_projection_bounds: normalized predicate = {:?}" , normalized_predicate) ;
1286
1265
1287
1266
inh. register_predicates ( obligations) ;
0 commit comments