@@ -330,7 +330,6 @@ fn compare_method_predicate_entailment<'tcx>(
330330 // lifetime parameters.
331331 let outlives_env = OutlivesEnvironment :: with_bounds (
332332 param_env,
333- Some ( infcx) ,
334333 infcx. implied_bounds_tys ( param_env, impl_m_def_id, wf_tys. clone ( ) ) ,
335334 ) ;
336335 infcx. process_registered_region_obligations (
@@ -727,7 +726,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
727726 // lifetime parameters.
728727 let outlives_environment = OutlivesEnvironment :: with_bounds (
729728 param_env,
730- Some ( infcx) ,
731729 infcx. implied_bounds_tys ( param_env, impl_m_def_id, wf_tys) ,
732730 ) ;
733731 infcx
@@ -1876,14 +1874,17 @@ pub(super) fn check_type_bounds<'tcx>(
18761874 impl_ty : ty:: AssocItem ,
18771875 impl_trait_ref : ty:: TraitRef < ' tcx > ,
18781876) -> Result < ( ) , ErrorGuaranteed > {
1877+ let param_env = tcx. param_env ( impl_ty. def_id ) ;
1878+ let container_id = impl_ty. container_id ( tcx) ;
18791879 // Given
18801880 //
18811881 // impl<A, B> Foo<u32> for (A, B) {
1882- // type Bar<C> =...
1882+ // type Bar<C> = Wrapper<A, B, C>
18831883 // }
18841884 //
18851885 // - `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)
1886+ // - `normalize_impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
1887+ // - `normalize_impl_ty` would be `Wrapper<A, B, ^0.0>`
18871888 // - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from
18881889 // the *trait* with the generic associated type parameters (as bound vars).
18891890 //
@@ -1912,56 +1913,46 @@ pub(super) fn check_type_bounds<'tcx>(
19121913 // Member<C: Eq> = .... That type would fail a well-formedness check that we ought to be doing
19131914 // elsewhere, which would check that any <T as Family>::Member<X> meets the bounds declared in
19141915 // 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- }
19231916 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_identity ( ) ;
1962-
1963- let param_env = tcx. param_env ( impl_ty. def_id ) ;
1964-
1917+ smallvec:: SmallVec :: with_capacity ( tcx. generics_of ( impl_ty. def_id ) . params . len ( ) ) ;
1918+ // Extend the impl's identity substs with late-bound GAT vars
1919+ let normalize_impl_ty_substs = ty:: InternalSubsts :: identity_for_item ( tcx, container_id)
1920+ . extend_to ( tcx, impl_ty. def_id , |param, _| match param. kind {
1921+ GenericParamDefKind :: Type { .. } => {
1922+ let kind = ty:: BoundTyKind :: Param ( param. def_id , param. name ) ;
1923+ let bound_var = ty:: BoundVariableKind :: Ty ( kind) ;
1924+ bound_vars. push ( bound_var) ;
1925+ tcx. mk_bound (
1926+ ty:: INNERMOST ,
1927+ ty:: BoundTy { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
1928+ )
1929+ . into ( )
1930+ }
1931+ GenericParamDefKind :: Lifetime => {
1932+ let kind = ty:: BoundRegionKind :: BrNamed ( param. def_id , param. name ) ;
1933+ let bound_var = ty:: BoundVariableKind :: Region ( kind) ;
1934+ bound_vars. push ( bound_var) ;
1935+ tcx. mk_re_late_bound (
1936+ ty:: INNERMOST ,
1937+ ty:: BoundRegion { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
1938+ )
1939+ . into ( )
1940+ }
1941+ GenericParamDefKind :: Const { .. } => {
1942+ let bound_var = ty:: BoundVariableKind :: Const ;
1943+ bound_vars. push ( bound_var) ;
1944+ tcx. mk_const (
1945+ ty:: ConstKind :: Bound (
1946+ ty:: INNERMOST ,
1947+ ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
1948+ ) ,
1949+ tcx. type_of ( param. def_id )
1950+ . no_bound_vars ( )
1951+ . expect ( "const parameter types cannot be generic" ) ,
1952+ )
1953+ . into ( )
1954+ }
1955+ } ) ;
19651956 // When checking something like
19661957 //
19671958 // trait X { type Y: PartialEq<<Self as X>::Y> }
@@ -1971,9 +1962,13 @@ pub(super) fn check_type_bounds<'tcx>(
19711962 // we want <T as X>::Y to normalize to S. This is valid because we are
19721963 // checking the default value specifically here. Add this equality to the
19731964 // ParamEnv for normalization specifically.
1965+ let normalize_impl_ty = tcx. type_of ( impl_ty. def_id ) . subst ( tcx, normalize_impl_ty_substs) ;
1966+ let rebased_substs =
1967+ normalize_impl_ty_substs. rebase_onto ( tcx, container_id, impl_trait_ref. substs ) ;
1968+ let bound_vars = tcx. mk_bound_variable_kinds ( & bound_vars) ;
19741969 let normalize_param_env = {
19751970 let mut predicates = param_env. caller_bounds ( ) . iter ( ) . collect :: < Vec < _ > > ( ) ;
1976- match impl_ty_value . kind ( ) {
1971+ match normalize_impl_ty . kind ( ) {
19771972 ty:: Alias ( ty:: Projection , proj)
19781973 if proj. def_id == trait_ty. def_id && proj. substs == rebased_substs =>
19791974 {
@@ -1987,7 +1982,7 @@ pub(super) fn check_type_bounds<'tcx>(
19871982 ty:: Binder :: bind_with_vars (
19881983 ty:: ProjectionPredicate {
19891984 projection_ty : tcx. mk_alias_ty ( trait_ty. def_id , rebased_substs) ,
1990- term : impl_ty_value . into ( ) ,
1985+ term : normalize_impl_ty . into ( ) ,
19911986 } ,
19921987 bound_vars,
19931988 )
@@ -2068,8 +2063,7 @@ pub(super) fn check_type_bounds<'tcx>(
20682063 // Finally, resolve all regions. This catches wily misuses of
20692064 // lifetime parameters.
20702065 let implied_bounds = infcx. implied_bounds_tys ( param_env, impl_ty_def_id, assumed_wf_types) ;
2071- let outlives_environment =
2072- OutlivesEnvironment :: with_bounds ( param_env, Some ( & infcx) , implied_bounds) ;
2066+ let outlives_environment = OutlivesEnvironment :: with_bounds ( param_env, implied_bounds) ;
20732067
20742068 infcx. err_ctxt ( ) . check_region_obligations_and_report_errors (
20752069 impl_ty. def_id . expect_local ( ) ,
0 commit comments