@@ -1225,6 +1225,7 @@ fn compare_type_predicate_entailment<'tcx>(
12251225/// For default associated types the normalization is not possible (the value
12261226/// from the impl could be overridden). We also can't normalize generic
12271227/// associated types (yet) because they contain bound parameters.
1228+ #[ tracing:: instrument( level = "debug" , skip( tcx) ) ]
12281229pub fn check_type_bounds < ' tcx > (
12291230 tcx : TyCtxt < ' tcx > ,
12301231 trait_ty : & ty:: AssocItem ,
@@ -1238,10 +1239,83 @@ pub fn check_type_bounds<'tcx>(
12381239 // type Bar<C> =...
12391240 // }
12401241 //
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+
12451319 let rebased_substs =
12461320 impl_ty_substs. rebase_onto ( tcx, impl_ty. container . id ( ) , impl_trait_ref. substs ) ;
12471321 let impl_ty_value = tcx. type_of ( impl_ty. def_id ) ;
@@ -1270,18 +1344,26 @@ pub fn check_type_bounds<'tcx>(
12701344 // impl<T> X for T where T: X { type Y = <T as X>::Y; }
12711345 }
12721346 _ => 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,
12771354 } ,
1278- ty : impl_ty_value ,
1279- } )
1355+ bound_vars ,
1356+ )
12801357 . to_predicate ( tcx) ,
12811358 ) ,
12821359 } ;
12831360 ty:: ParamEnv :: new ( tcx. intern_predicates ( & predicates) , Reveal :: UserFacing )
12841361 } ;
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 ) ;
12851367
12861368 tcx. infer_ctxt ( ) . enter ( move |infcx| {
12871369 let constness = impl_ty
@@ -1308,6 +1390,7 @@ pub fn check_type_bounds<'tcx>(
13081390 . explicit_item_bounds ( trait_ty. def_id )
13091391 . iter ( )
13101392 . map ( |& ( bound, span) | {
1393+ debug ! ( ?bound) ;
13111394 let concrete_ty_bound = bound. subst ( tcx, rebased_substs) ;
13121395 debug ! ( "check_type_bounds: concrete_ty_bound = {:?}" , concrete_ty_bound) ;
13131396
0 commit comments