@@ -1876,14 +1876,17 @@ pub(super) fn check_type_bounds<'tcx>(
1876
1876
impl_ty : ty:: AssocItem ,
1877
1877
impl_trait_ref : ty:: TraitRef < ' tcx > ,
1878
1878
) -> Result < ( ) , ErrorGuaranteed > {
1879
+ let param_env = tcx. param_env ( impl_ty. def_id ) ;
1880
+ let container_id = impl_ty. container_id ( tcx) ;
1879
1881
// Given
1880
1882
//
1881
1883
// impl<A, B> Foo<u32> for (A, B) {
1882
- // type Bar<C> =...
1884
+ // type Bar<C> = Wrapper<A, B, C>
1883
1885
// }
1884
1886
//
1885
1887
// - `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>`
1887
1890
// - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from
1888
1891
// the *trait* with the generic associated type parameters (as bound vars).
1889
1892
//
@@ -1912,56 +1915,46 @@ pub(super) fn check_type_bounds<'tcx>(
1912
1915
// Member<C: Eq> = .... That type would fail a well-formedness check that we ought to be doing
1913
1916
// elsewhere, which would check that any <T as Family>::Member<X> meets the bounds declared in
1914
1917
// 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
- }
1923
1918
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
+ } ) ;
1965
1958
// When checking something like
1966
1959
//
1967
1960
// trait X { type Y: PartialEq<<Self as X>::Y> }
@@ -1971,9 +1964,13 @@ pub(super) fn check_type_bounds<'tcx>(
1971
1964
// we want <T as X>::Y to normalize to S. This is valid because we are
1972
1965
// checking the default value specifically here. Add this equality to the
1973
1966
// 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) ;
1974
1971
let normalize_param_env = {
1975
1972
let mut predicates = param_env. caller_bounds ( ) . iter ( ) . collect :: < Vec < _ > > ( ) ;
1976
- match impl_ty_value . kind ( ) {
1973
+ match normalize_impl_ty . kind ( ) {
1977
1974
ty:: Alias ( ty:: Projection , proj)
1978
1975
if proj. def_id == trait_ty. def_id && proj. substs == rebased_substs =>
1979
1976
{
@@ -1987,7 +1984,7 @@ pub(super) fn check_type_bounds<'tcx>(
1987
1984
ty:: Binder :: bind_with_vars (
1988
1985
ty:: ProjectionPredicate {
1989
1986
projection_ty : tcx. mk_alias_ty ( trait_ty. def_id , rebased_substs) ,
1990
- term : impl_ty_value . into ( ) ,
1987
+ term : normalize_impl_ty . into ( ) ,
1991
1988
} ,
1992
1989
bound_vars,
1993
1990
)
0 commit comments