@@ -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