@@ -2162,7 +2162,7 @@ pub(super) fn check_type_bounds<'tcx>(
2162
2162
impl_ty : ty:: AssocItem ,
2163
2163
impl_trait_ref : ty:: TraitRef < ' tcx > ,
2164
2164
) -> 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) ;
2166
2166
debug ! ( ?param_env) ;
2167
2167
2168
2168
let container_id = impl_ty. container_id ( tcx) ;
@@ -2288,92 +2288,118 @@ pub(super) fn check_type_bounds<'tcx>(
2288
2288
/// the trait (notably, that `X: Eq` and `T: Family`).
2289
2289
fn param_env_with_gat_bounds < ' tcx > (
2290
2290
tcx : TyCtxt < ' tcx > ,
2291
- trait_ty : ty:: AssocItem ,
2292
2291
impl_ty : ty:: AssocItem ,
2293
2292
impl_trait_ref : ty:: TraitRef < ' tcx > ,
2294
2293
) -> ty:: ParamEnv < ' tcx > {
2295
2294
let param_env = tcx. param_env ( impl_ty. def_id ) ;
2296
2295
let container_id = impl_ty. container_id ( tcx) ;
2297
2296
let mut predicates = param_env. caller_bounds ( ) . to_vec ( ) ;
2298
2297
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 ( ) )
2316
2319
}
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; }
2327
2390
}
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,
2338
2398
)
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
+ }
2377
2403
2378
2404
ty:: ParamEnv :: new ( tcx. mk_clauses ( & predicates) , Reveal :: UserFacing )
2379
2405
}
0 commit comments