@@ -2162,7 +2162,7 @@ pub(super) fn check_type_bounds<'tcx>(
21622162 impl_ty : ty:: AssocItem ,
21632163 impl_trait_ref : ty:: TraitRef < ' tcx > ,
21642164) -> Result < ( ) , ErrorGuaranteed > {
2165- let param_env = param_env_with_gat_bounds ( tcx, trait_ty , impl_ty, impl_trait_ref) ;
2165+ let param_env = param_env_with_gat_bounds ( tcx, impl_ty, impl_trait_ref) ;
21662166 debug ! ( ?param_env) ;
21672167
21682168 let container_id = impl_ty. container_id ( tcx) ;
@@ -2288,92 +2288,118 @@ pub(super) fn check_type_bounds<'tcx>(
22882288/// the trait (notably, that `X: Eq` and `T: Family`).
22892289fn param_env_with_gat_bounds < ' tcx > (
22902290 tcx : TyCtxt < ' tcx > ,
2291- trait_ty : ty:: AssocItem ,
22922291 impl_ty : ty:: AssocItem ,
22932292 impl_trait_ref : ty:: TraitRef < ' tcx > ,
22942293) -> ty:: ParamEnv < ' tcx > {
22952294 let param_env = tcx. param_env ( impl_ty. def_id ) ;
22962295 let container_id = impl_ty. container_id ( tcx) ;
22972296 let mut predicates = param_env. caller_bounds ( ) . to_vec ( ) ;
22982297
2299- let mut bound_vars: smallvec:: SmallVec < [ ty:: BoundVariableKind ; 8 ] > =
2300- smallvec:: SmallVec :: with_capacity ( tcx. generics_of ( impl_ty. def_id ) . params . len ( ) ) ;
2301- // Extend the impl's identity args with late-bound GAT vars
2302- let normalize_impl_ty_args = ty:: GenericArgs :: identity_for_item ( tcx, container_id) . extend_to (
2303- tcx,
2304- impl_ty. def_id ,
2305- |param, _| match param. kind {
2306- GenericParamDefKind :: Type { .. } => {
2307- let kind = ty:: BoundTyKind :: Param ( param. def_id , param. name ) ;
2308- let bound_var = ty:: BoundVariableKind :: Ty ( kind) ;
2309- bound_vars. push ( bound_var) ;
2310- Ty :: new_bound (
2311- tcx,
2312- ty:: INNERMOST ,
2313- ty:: BoundTy { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
2314- )
2315- . into ( )
2298+ // for RPITITs, we should install predicates that allow us to project all
2299+ // of the RPITITs associated with the same body. This is because checking
2300+ // the item bounds of RPITITs often involves nested RPITITs having to prove
2301+ // bounds about themselves.
2302+ let impl_tys_to_install = match impl_ty. opt_rpitit_info {
2303+ None => vec ! [ impl_ty] ,
2304+ Some (
2305+ ty:: ImplTraitInTraitData :: Impl { fn_def_id }
2306+ | ty:: ImplTraitInTraitData :: Trait { fn_def_id, .. } ,
2307+ ) => tcx
2308+ . associated_types_for_impl_traits_in_associated_fn ( fn_def_id)
2309+ . iter ( )
2310+ . map ( |def_id| tcx. associated_item ( * def_id) )
2311+ . collect ( ) ,
2312+ } ;
2313+
2314+ for impl_ty in impl_tys_to_install {
2315+ let trait_ty = match impl_ty. container {
2316+ ty:: AssocItemContainer :: TraitContainer => impl_ty,
2317+ ty:: AssocItemContainer :: ImplContainer => {
2318+ tcx. associated_item ( impl_ty. trait_item_def_id . unwrap ( ) )
23162319 }
2317- GenericParamDefKind :: Lifetime => {
2318- let kind = ty:: BoundRegionKind :: BrNamed ( param. def_id , param. name ) ;
2319- let bound_var = ty:: BoundVariableKind :: Region ( kind) ;
2320- bound_vars. push ( bound_var) ;
2321- ty:: Region :: new_late_bound (
2322- tcx,
2323- ty:: INNERMOST ,
2324- ty:: BoundRegion { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
2325- )
2326- . into ( )
2320+ } ;
2321+
2322+ let mut bound_vars: smallvec:: SmallVec < [ ty:: BoundVariableKind ; 8 ] > =
2323+ smallvec:: SmallVec :: with_capacity ( tcx. generics_of ( impl_ty. def_id ) . params . len ( ) ) ;
2324+ // Extend the impl's identity args with late-bound GAT vars
2325+ let normalize_impl_ty_args = ty:: GenericArgs :: identity_for_item ( tcx, container_id)
2326+ . extend_to ( tcx, impl_ty. def_id , |param, _| match param. kind {
2327+ GenericParamDefKind :: Type { .. } => {
2328+ let kind = ty:: BoundTyKind :: Param ( param. def_id , param. name ) ;
2329+ let bound_var = ty:: BoundVariableKind :: Ty ( kind) ;
2330+ bound_vars. push ( bound_var) ;
2331+ Ty :: new_bound (
2332+ tcx,
2333+ ty:: INNERMOST ,
2334+ ty:: BoundTy { var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) , kind } ,
2335+ )
2336+ . into ( )
2337+ }
2338+ GenericParamDefKind :: Lifetime => {
2339+ let kind = ty:: BoundRegionKind :: BrNamed ( param. def_id , param. name ) ;
2340+ let bound_var = ty:: BoundVariableKind :: Region ( kind) ;
2341+ bound_vars. push ( bound_var) ;
2342+ ty:: Region :: new_late_bound (
2343+ tcx,
2344+ ty:: INNERMOST ,
2345+ ty:: BoundRegion {
2346+ var : ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
2347+ kind,
2348+ } ,
2349+ )
2350+ . into ( )
2351+ }
2352+ GenericParamDefKind :: Const { .. } => {
2353+ let bound_var = ty:: BoundVariableKind :: Const ;
2354+ bound_vars. push ( bound_var) ;
2355+ ty:: Const :: new_bound (
2356+ tcx,
2357+ ty:: INNERMOST ,
2358+ ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
2359+ tcx. type_of ( param. def_id )
2360+ . no_bound_vars ( )
2361+ . expect ( "const parameter types cannot be generic" ) ,
2362+ )
2363+ . into ( )
2364+ }
2365+ } ) ;
2366+ // When checking something like
2367+ //
2368+ // trait X { type Y: PartialEq<<Self as X>::Y> }
2369+ // impl X for T { default type Y = S; }
2370+ //
2371+ // We will have to prove the bound S: PartialEq<<T as X>::Y>. In this case
2372+ // we want <T as X>::Y to normalize to S. This is valid because we are
2373+ // checking the default value specifically here. Add this equality to the
2374+ // ParamEnv for normalization specifically.
2375+ let normalize_impl_ty =
2376+ tcx. type_of ( impl_ty. def_id ) . instantiate ( tcx, normalize_impl_ty_args) ;
2377+ let rebased_args =
2378+ normalize_impl_ty_args. rebase_onto ( tcx, container_id, impl_trait_ref. args ) ;
2379+ let bound_vars = tcx. mk_bound_variable_kinds ( & bound_vars) ;
2380+
2381+ match normalize_impl_ty. kind ( ) {
2382+ ty:: Alias ( ty:: Projection , proj)
2383+ if proj. def_id == trait_ty. def_id && proj. args == rebased_args =>
2384+ {
2385+ // Don't include this predicate if the projected type is
2386+ // exactly the same as the projection. This can occur in
2387+ // (somewhat dubious) code like this:
2388+ //
2389+ // impl<T> X for T where T: X { type Y = <T as X>::Y; }
23272390 }
2328- GenericParamDefKind :: Const { .. } => {
2329- let bound_var = ty:: BoundVariableKind :: Const ;
2330- bound_vars. push ( bound_var) ;
2331- ty:: Const :: new_bound (
2332- tcx,
2333- ty:: INNERMOST ,
2334- ty:: BoundVar :: from_usize ( bound_vars. len ( ) - 1 ) ,
2335- tcx. type_of ( param. def_id )
2336- . no_bound_vars ( )
2337- . expect ( "const parameter types cannot be generic" ) ,
2391+ _ => predicates. push (
2392+ ty:: Binder :: bind_with_vars (
2393+ ty:: ProjectionPredicate {
2394+ projection_ty : ty:: AliasTy :: new ( tcx, trait_ty. def_id , rebased_args) ,
2395+ term : normalize_impl_ty. into ( ) ,
2396+ } ,
2397+ bound_vars,
23382398 )
2339- . into ( )
2340- }
2341- } ,
2342- ) ;
2343- // When checking something like
2344- //
2345- // trait X { type Y: PartialEq<<Self as X>::Y> }
2346- // impl X for T { default type Y = S; }
2347- //
2348- // We will have to prove the bound S: PartialEq<<T as X>::Y>. In this case
2349- // we want <T as X>::Y to normalize to S. This is valid because we are
2350- // checking the default value specifically here. Add this equality to the
2351- // ParamEnv for normalization specifically.
2352- let normalize_impl_ty = tcx. type_of ( impl_ty. def_id ) . instantiate ( tcx, normalize_impl_ty_args) ;
2353- let rebased_args = normalize_impl_ty_args. rebase_onto ( tcx, container_id, impl_trait_ref. args ) ;
2354- let bound_vars = tcx. mk_bound_variable_kinds ( & bound_vars) ;
2355-
2356- match normalize_impl_ty. kind ( ) {
2357- ty:: Alias ( ty:: Projection , proj)
2358- if proj. def_id == trait_ty. def_id && proj. args == rebased_args =>
2359- {
2360- // Don't include this predicate if the projected type is
2361- // exactly the same as the projection. This can occur in
2362- // (somewhat dubious) code like this:
2363- //
2364- // impl<T> X for T where T: X { type Y = <T as X>::Y; }
2365- }
2366- _ => predicates. push (
2367- ty:: Binder :: bind_with_vars (
2368- ty:: ProjectionPredicate {
2369- projection_ty : ty:: AliasTy :: new ( tcx, trait_ty. def_id , rebased_args) ,
2370- term : normalize_impl_ty. into ( ) ,
2371- } ,
2372- bound_vars,
2373- )
2374- . to_predicate ( tcx) ,
2375- ) ,
2376- } ;
2399+ . to_predicate ( tcx) ,
2400+ ) ,
2401+ } ;
2402+ }
23772403
23782404 ty:: ParamEnv :: new ( tcx. mk_clauses ( & predicates) , Reveal :: UserFacing )
23792405}
0 commit comments