@@ -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,83 @@ 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]` (`^0.0` here is the bound var with db 0 and index 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
+ //
1247
+ // A note regarding the use of bound vars here:
1248
+ // Imagine as an example
1249
+ // ```
1250
+ // trait Family {
1251
+ // type Member<C: Eq>;
1252
+ // }
1253
+ //
1254
+ // impl Family for VecFamily {
1255
+ // type Member<C: Eq> = i32;
1256
+ // }
1257
+ // ```
1258
+ // Here, we would generate
1259
+ // ```notrust
1260
+ // forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) }
1261
+ // ```
1262
+ // when we really would like to generate
1263
+ // ```notrust
1264
+ // forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) :- Implemented(C: Eq) }
1265
+ // ```
1266
+ // But, this is probably fine, because although the first clause can be used with types C that
1267
+ // do not implement Eq, for it to cause some kind of problem, there would have to be a
1268
+ // VecFamily::Member<X> for some type X where !(X: Eq), that appears in the value of type
1269
+ // Member<C: Eq> = .... That type would fail a well-formedness check that we ought to be doing
1270
+ // elsewhere, which would check that any <T as Family>::Member<X> meets the bounds declared in
1271
+ // the trait (notably, that X: Eq and T: Family).
1272
+ let defs: & ty:: Generics = tcx. generics_of ( impl_ty. def_id ) ;
1273
+ let mut substs = smallvec:: SmallVec :: with_capacity ( defs. count ( ) ) ;
1274
+ if let Some ( def_id) = defs. parent {
1275
+ let parent_defs = tcx. generics_of ( def_id) ;
1276
+ InternalSubsts :: fill_item ( & mut substs, tcx, parent_defs, & mut |param, _| {
1277
+ tcx. mk_param_from_def ( param)
1278
+ } ) ;
1279
+ }
1280
+ let mut bound_vars: smallvec:: SmallVec < [ ty:: BoundVariableKind ; 8 ] > =
1281
+ smallvec:: SmallVec :: with_capacity ( defs. count ( ) ) ;
1282
+ InternalSubsts :: fill_single ( & mut substs, defs, & mut |param, _| match param. kind {
1283
+ GenericParamDefKind :: Type { .. } => {
1284
+ let kind = ty:: BoundTyKind :: Param ( param. name ) ;
1285
+ let bound_var = ty:: BoundVariableKind :: Ty ( kind) ;
1286
+ bound_vars. push ( bound_var) ;
1287
+ tcx. mk_ty ( ty:: Bound (
1288
+ ty:: INNERMOST ,
1289
+ ty:: BoundTy { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
1290
+ ) )
1291
+ . into ( )
1292
+ }
1293
+ GenericParamDefKind :: Lifetime => {
1294
+ let kind = ty:: BoundRegionKind :: BrNamed ( param. def_id , param. name ) ;
1295
+ let bound_var = ty:: BoundVariableKind :: Region ( kind) ;
1296
+ bound_vars. push ( bound_var) ;
1297
+ tcx. mk_region ( ty:: ReLateBound (
1298
+ ty:: INNERMOST ,
1299
+ ty:: BoundRegion { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
1300
+ ) )
1301
+ . into ( )
1302
+ }
1303
+ GenericParamDefKind :: Const { .. } => {
1304
+ let bound_var = ty:: BoundVariableKind :: Const ;
1305
+ bound_vars. push ( bound_var) ;
1306
+ tcx. mk_const ( ty:: Const {
1307
+ ty : tcx. type_of ( param. def_id ) ,
1308
+ val : ty:: ConstKind :: Bound (
1309
+ ty:: INNERMOST ,
1310
+ ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
1311
+ ) ,
1312
+ } )
1313
+ . into ( )
1314
+ }
1315
+ } ) ;
1316
+ let bound_vars = tcx. mk_bound_variable_kinds ( bound_vars. into_iter ( ) ) ;
1317
+ let impl_ty_substs = tcx. intern_substs ( & substs) ;
1318
+
1245
1319
let rebased_substs =
1246
1320
impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
1247
1321
let impl_ty_value = tcx. type_of ( impl_ty. def_id ) ;
@@ -1270,18 +1344,26 @@ pub fn check_type_bounds<'tcx>(
1270
1344
// impl<T> X for T where T: X { type Y = <T as X>::Y; }
1271
1345
}
1272
1346
_ => 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,
1347
+ ty:: Binder :: bind_with_vars (
1348
+ ty:: ProjectionPredicate {
1349
+ projection_ty : ty:: ProjectionTy {
1350
+ item_def_id : trait_ty. def_id ,
1351
+ substs : rebased_substs,
1352
+ } ,
1353
+ ty : impl_ty_value,
1277
1354
} ,
1278
- ty : impl_ty_value ,
1279
- } )
1355
+ bound_vars ,
1356
+ )
1280
1357
. to_predicate ( tcx) ,
1281
1358
) ,
1282
1359
} ;
1283
1360
ty:: ParamEnv :: new ( tcx. intern_predicates ( & predicates) , Reveal :: UserFacing )
1284
1361
} ;
1362
+ debug ! ( ?normalize_param_env) ;
1363
+
1364
+ let impl_ty_substs = InternalSubsts :: identity_for_item ( tcx, impl_ty. def_id ) ;
1365
+ let rebased_substs =
1366
+ impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
1285
1367
1286
1368
tcx. infer_ctxt ( ) . enter ( move |infcx| {
1287
1369
let constness = impl_ty
@@ -1308,6 +1390,7 @@ pub fn check_type_bounds<'tcx>(
1308
1390
. explicit_item_bounds ( trait_ty. def_id )
1309
1391
. iter ( )
1310
1392
. map ( |& ( bound, span) | {
1393
+ debug ! ( ?bound) ;
1311
1394
let concrete_ty_bound = bound. subst ( tcx, rebased_substs) ;
1312
1395
debug ! ( "check_type_bounds: concrete_ty_bound = {:?}" , concrete_ty_bound) ;
1313
1396
0 commit comments