@@ -1876,14 +1876,17 @@ pub(super) fn check_type_bounds<'tcx>(
18761876    impl_ty :  ty:: AssocItem , 
18771877    impl_trait_ref :  ty:: TraitRef < ' tcx > , 
18781878)  -> Result < ( ) ,  ErrorGuaranteed >  { 
1879+     let  param_env = tcx. param_env ( impl_ty. def_id ) ; 
1880+     let  container_id = impl_ty. container_id ( tcx) ; 
18791881    // Given 
18801882    // 
18811883    // impl<A, B> Foo<u32> for (A, B) { 
1882-     //     type Bar<C> =...  
1884+     //     type Bar<C> = Wrapper<A, B, C>  
18831885    // } 
18841886    // 
18851887    // - `impl_trait_ref` would be `<(A, B) as Foo<u32>>` 
1886-     // - `impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0) 
1888+     // - `normalize_impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0) 
1889+     // - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>` 
18871890    // - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from 
18881891    //    the *trait* with the generic associated type parameters (as bound vars). 
18891892    // 
@@ -1912,56 +1915,46 @@ pub(super) fn check_type_bounds<'tcx>(
19121915    // Member<C: Eq> = .... That type would fail a well-formedness check that we ought to be doing 
19131916    // elsewhere, which would check that any <T as Family>::Member<X> meets the bounds declared in 
19141917    // the trait (notably, that X: Eq and T: Family). 
1915-     let  defs:  & ty:: Generics  = tcx. generics_of ( impl_ty. def_id ) ; 
1916-     let  mut  substs = smallvec:: SmallVec :: with_capacity ( defs. count ( ) ) ; 
1917-     if  let  Some ( def_id)  = defs. parent  { 
1918-         let  parent_defs = tcx. generics_of ( def_id) ; 
1919-         InternalSubsts :: fill_item ( & mut  substs,  tcx,  parent_defs,  & mut  |param,  _| { 
1920-             tcx. mk_param_from_def ( param) 
1921-         } ) ; 
1922-     } 
19231918    let  mut  bound_vars:  smallvec:: SmallVec < [ ty:: BoundVariableKind ;  8 ] >  =
1924-         smallvec:: SmallVec :: with_capacity ( defs. count ( ) ) ; 
1925-     InternalSubsts :: fill_single ( & mut  substs,  defs,  & mut  |param,  _| match  param. kind  { 
1926-         GenericParamDefKind :: Type  {  .. }  => { 
1927-             let  kind = ty:: BoundTyKind :: Param ( param. def_id ,  param. name ) ; 
1928-             let  bound_var = ty:: BoundVariableKind :: Ty ( kind) ; 
1929-             bound_vars. push ( bound_var) ; 
1930-             tcx. mk_bound ( 
1931-                 ty:: INNERMOST , 
1932-                 ty:: BoundTy  {  var :  ty:: BoundVar :: from_usize ( bound_vars. len ( )  - 1 ) ,  kind } , 
1933-             ) 
1934-             . into ( ) 
1935-         } 
1936-         GenericParamDefKind :: Lifetime  => { 
1937-             let  kind = ty:: BoundRegionKind :: BrNamed ( param. def_id ,  param. name ) ; 
1938-             let  bound_var = ty:: BoundVariableKind :: Region ( kind) ; 
1939-             bound_vars. push ( bound_var) ; 
1940-             tcx. mk_re_late_bound ( 
1941-                 ty:: INNERMOST , 
1942-                 ty:: BoundRegion  {  var :  ty:: BoundVar :: from_usize ( bound_vars. len ( )  - 1 ) ,  kind } , 
1943-             ) 
1944-             . into ( ) 
1945-         } 
1946-         GenericParamDefKind :: Const  {  .. }  => { 
1947-             let  bound_var = ty:: BoundVariableKind :: Const ; 
1948-             bound_vars. push ( bound_var) ; 
1949-             tcx. mk_const ( 
1950-                 ty:: ConstKind :: Bound ( ty:: INNERMOST ,  ty:: BoundVar :: from_usize ( bound_vars. len ( )  - 1 ) ) , 
1951-                 tcx. type_of ( param. def_id ) . subst_identity ( ) , 
1952-             ) 
1953-             . into ( ) 
1954-         } 
1955-     } ) ; 
1956-     let  bound_vars = tcx. mk_bound_variable_kinds ( & bound_vars) ; 
1957-     let  impl_ty_substs = tcx. mk_substs ( & substs) ; 
1958-     let  container_id = impl_ty. container_id ( tcx) ; 
1959- 
1960-     let  rebased_substs = impl_ty_substs. rebase_onto ( tcx,  container_id,  impl_trait_ref. substs ) ; 
1961-     let  impl_ty_value = tcx. type_of ( impl_ty. def_id ) . subst ( tcx,  impl_ty_substs) ; 
1962- 
1963-     let  param_env = tcx. param_env ( impl_ty. def_id ) ; 
1964- 
1919+         smallvec:: SmallVec :: with_capacity ( tcx. generics_of ( impl_ty. def_id ) . params . len ( ) ) ; 
1920+     // Extend the impl's identity substs with late-bound GAT vars 
1921+     let  normalize_impl_ty_substs = ty:: InternalSubsts :: identity_for_item ( tcx,  container_id) 
1922+         . extend_to ( tcx,  impl_ty. def_id ,  |param,  _| match  param. kind  { 
1923+             GenericParamDefKind :: Type  {  .. }  => { 
1924+                 let  kind = ty:: BoundTyKind :: Param ( param. def_id ,  param. name ) ; 
1925+                 let  bound_var = ty:: BoundVariableKind :: Ty ( kind) ; 
1926+                 bound_vars. push ( bound_var) ; 
1927+                 tcx. mk_bound ( 
1928+                     ty:: INNERMOST , 
1929+                     ty:: BoundTy  {  var :  ty:: BoundVar :: from_usize ( bound_vars. len ( )  - 1 ) ,  kind } , 
1930+                 ) 
1931+                 . into ( ) 
1932+             } 
1933+             GenericParamDefKind :: Lifetime  => { 
1934+                 let  kind = ty:: BoundRegionKind :: BrNamed ( param. def_id ,  param. name ) ; 
1935+                 let  bound_var = ty:: BoundVariableKind :: Region ( kind) ; 
1936+                 bound_vars. push ( bound_var) ; 
1937+                 tcx. mk_re_late_bound ( 
1938+                     ty:: INNERMOST , 
1939+                     ty:: BoundRegion  {  var :  ty:: BoundVar :: from_usize ( bound_vars. len ( )  - 1 ) ,  kind } , 
1940+                 ) 
1941+                 . into ( ) 
1942+             } 
1943+             GenericParamDefKind :: Const  {  .. }  => { 
1944+                 let  bound_var = ty:: BoundVariableKind :: Const ; 
1945+                 bound_vars. push ( bound_var) ; 
1946+                 tcx. mk_const ( 
1947+                     ty:: ConstKind :: Bound ( 
1948+                         ty:: INNERMOST , 
1949+                         ty:: BoundVar :: from_usize ( bound_vars. len ( )  - 1 ) , 
1950+                     ) , 
1951+                     tcx. type_of ( param. def_id ) 
1952+                         . no_bound_vars ( ) 
1953+                         . expect ( "const parameter types cannot be generic" ) , 
1954+                 ) 
1955+                 . into ( ) 
1956+             } 
1957+         } ) ; 
19651958    // When checking something like 
19661959    // 
19671960    // trait X { type Y: PartialEq<<Self as X>::Y> } 
@@ -1971,9 +1964,13 @@ pub(super) fn check_type_bounds<'tcx>(
19711964    // we want <T as X>::Y to normalize to S. This is valid because we are 
19721965    // checking the default value specifically here. Add this equality to the 
19731966    // ParamEnv for normalization specifically. 
1967+     let  normalize_impl_ty = tcx. type_of ( impl_ty. def_id ) . subst ( tcx,  normalize_impl_ty_substs) ; 
1968+     let  rebased_substs =
1969+         normalize_impl_ty_substs. rebase_onto ( tcx,  container_id,  impl_trait_ref. substs ) ; 
1970+     let  bound_vars = tcx. mk_bound_variable_kinds ( & bound_vars) ; 
19741971    let  normalize_param_env = { 
19751972        let  mut  predicates = param_env. caller_bounds ( ) . iter ( ) . collect :: < Vec < _ > > ( ) ; 
1976-         match  impl_ty_value . kind ( )  { 
1973+         match  normalize_impl_ty . kind ( )  { 
19771974            ty:: Alias ( ty:: Projection ,  proj) 
19781975                if  proj. def_id  == trait_ty. def_id  && proj. substs  == rebased_substs =>
19791976            { 
@@ -1987,7 +1984,7 @@ pub(super) fn check_type_bounds<'tcx>(
19871984                ty:: Binder :: bind_with_vars ( 
19881985                    ty:: ProjectionPredicate  { 
19891986                        projection_ty :  tcx. mk_alias_ty ( trait_ty. def_id ,  rebased_substs) , 
1990-                         term :  impl_ty_value . into ( ) , 
1987+                         term :  normalize_impl_ty . into ( ) , 
19911988                    } , 
19921989                    bound_vars, 
19931990                ) 
0 commit comments