@@ -1225,6 +1225,7 @@ fn compare_type_predicate_entailment<'tcx>(
1225
1225
/// For default associated types the normalization is not possible (the value
1226
1226
/// from the impl could be overridden). We also can't normalize generic
1227
1227
/// associated types (yet) because they contain bound parameters.
1228
+ #[ tracing:: instrument( level = "debug" , skip( tcx) ) ]
1228
1229
pub fn check_type_bounds < ' tcx > (
1229
1230
tcx : TyCtxt < ' tcx > ,
1230
1231
trait_ty : & ty:: AssocItem ,
@@ -1238,10 +1239,57 @@ pub fn check_type_bounds<'tcx>(
1238
1239
// type Bar<C> =...
1239
1240
// }
1240
1241
//
1241
- // - `impl_substs` would be `[A, B, C]`
1242
- // - `rebased_substs` would be `[(A, B), u32, C]`, combining the substs from
1243
- // the *trait* with the generic associated type parameters.
1244
- let impl_ty_substs = InternalSubsts :: identity_for_item ( tcx, impl_ty. def_id ) ;
1242
+ // - `impl_trait_ref` would be `<(A, B) as Foo<u32>>
1243
+ // - `impl_ty_substs` would be `[A, B, ^0.0]`
1244
+ // - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from
1245
+ // the *trait* with the generic associated type parameters (as bound vars).
1246
+ let defs: & ty:: Generics = tcx. generics_of ( impl_ty. def_id ) ;
1247
+ let mut substs = smallvec:: SmallVec :: with_capacity ( defs. count ( ) ) ;
1248
+ if let Some ( def_id) = defs. parent {
1249
+ let parent_defs = tcx. generics_of ( def_id) ;
1250
+ InternalSubsts :: fill_item ( & mut substs, tcx, parent_defs, & mut |param, _| {
1251
+ tcx. mk_param_from_def ( param)
1252
+ } ) ;
1253
+ }
1254
+ let mut bound_vars: smallvec:: SmallVec < [ ty:: BoundVariableKind ; 8 ] > =
1255
+ smallvec:: SmallVec :: with_capacity ( defs. count ( ) ) ;
1256
+ InternalSubsts :: fill_single ( & mut substs, defs, & mut |param, _| match param. kind {
1257
+ GenericParamDefKind :: Type { .. } => {
1258
+ let kind = ty:: BoundTyKind :: Param ( param. name ) ;
1259
+ let bound_var = ty:: BoundVariableKind :: Ty ( kind) ;
1260
+ bound_vars. push ( bound_var) ;
1261
+ tcx. mk_ty ( ty:: Bound (
1262
+ ty:: INNERMOST ,
1263
+ ty:: BoundTy { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
1264
+ ) )
1265
+ . into ( )
1266
+ }
1267
+ GenericParamDefKind :: Lifetime => {
1268
+ let kind = ty:: BoundRegionKind :: BrNamed ( param. def_id , param. name ) ;
1269
+ let bound_var = ty:: BoundVariableKind :: Region ( kind) ;
1270
+ bound_vars. push ( bound_var) ;
1271
+ tcx. mk_region ( ty:: ReLateBound (
1272
+ ty:: INNERMOST ,
1273
+ ty:: BoundRegion { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
1274
+ ) )
1275
+ . into ( )
1276
+ }
1277
+ GenericParamDefKind :: Const { .. } => {
1278
+ let bound_var = ty:: BoundVariableKind :: Const ;
1279
+ bound_vars. push ( bound_var) ;
1280
+ tcx. mk_const ( ty:: Const {
1281
+ ty : tcx. type_of ( param. def_id ) ,
1282
+ val : ty:: ConstKind :: Bound (
1283
+ ty:: INNERMOST ,
1284
+ ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
1285
+ ) ,
1286
+ } )
1287
+ . into ( )
1288
+ }
1289
+ } ) ;
1290
+ let bound_vars = tcx. mk_bound_variable_kinds ( bound_vars. into_iter ( ) ) ;
1291
+ let impl_ty_substs = tcx. intern_substs ( & substs) ;
1292
+
1245
1293
let rebased_substs =
1246
1294
impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
1247
1295
let impl_ty_value = tcx. type_of ( impl_ty. def_id ) ;
@@ -1270,18 +1318,26 @@ pub fn check_type_bounds<'tcx>(
1270
1318
// impl<T> X for T where T: X { type Y = <T as X>::Y; }
1271
1319
}
1272
1320
_ => predicates. push (
1273
- ty:: Binder :: dummy ( ty:: ProjectionPredicate {
1274
- projection_ty : ty:: ProjectionTy {
1275
- item_def_id : trait_ty. def_id ,
1276
- substs : rebased_substs,
1321
+ ty:: Binder :: bind_with_vars (
1322
+ ty:: ProjectionPredicate {
1323
+ projection_ty : ty:: ProjectionTy {
1324
+ item_def_id : trait_ty. def_id ,
1325
+ substs : rebased_substs,
1326
+ } ,
1327
+ ty : impl_ty_value,
1277
1328
} ,
1278
- ty : impl_ty_value ,
1279
- } )
1329
+ bound_vars ,
1330
+ )
1280
1331
. to_predicate ( tcx) ,
1281
1332
) ,
1282
1333
} ;
1283
1334
ty:: ParamEnv :: new ( tcx. intern_predicates ( & predicates) , Reveal :: UserFacing )
1284
1335
} ;
1336
+ debug ! ( ?normalize_param_env) ;
1337
+
1338
+ let impl_ty_substs = InternalSubsts :: identity_for_item ( tcx, impl_ty. def_id ) ;
1339
+ let rebased_substs =
1340
+ impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
1285
1341
1286
1342
tcx. infer_ctxt ( ) . enter ( move |infcx| {
1287
1343
let constness = impl_ty
@@ -1308,6 +1364,7 @@ pub fn check_type_bounds<'tcx>(
1308
1364
. explicit_item_bounds ( trait_ty. def_id )
1309
1365
. iter ( )
1310
1366
. map ( |& ( bound, span) | {
1367
+ debug ! ( ?bound) ;
1311
1368
let concrete_ty_bound = bound. subst ( tcx, rebased_substs) ;
1312
1369
debug ! ( "check_type_bounds: concrete_ty_bound = {:?}" , concrete_ty_bound) ;
1313
1370
0 commit comments