@@ -314,9 +314,10 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
314
314
/// fn into_iter<'a>(&'a self) -> Self::Iter<'a>;
315
315
/// }
316
316
/// ```
317
- fn check_gat_where_clauses ( tcx : TyCtxt < ' _ > , associated_items : & [ hir :: TraitItemRef ] ) {
317
+ fn check_gat_where_clauses ( tcx : TyCtxt < ' _ > , trait_def_id : LocalDefId ) {
318
318
// Associates every GAT's def_id to a list of possibly missing bounds detected by this lint.
319
319
let mut required_bounds_by_item = FxHashMap :: default ( ) ;
320
+ let associated_items = tcx. associated_items ( trait_def_id) ;
320
321
321
322
// Loop over all GATs together, because if this lint suggests adding a where-clause bound
322
323
// to one GAT, it might then require us to an additional bound on another GAT.
@@ -325,8 +326,8 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
325
326
// those GATs.
326
327
loop {
327
328
let mut should_continue = false ;
328
- for gat_item in associated_items {
329
- let gat_def_id = gat_item. id . owner_id ;
329
+ for gat_item in associated_items. in_definition_order ( ) {
330
+ let gat_def_id = gat_item. def_id . expect_local ( ) ;
330
331
let gat_item = tcx. associated_item ( gat_def_id) ;
331
332
// If this item is not an assoc ty, or has no args, then it's not a GAT
332
333
if gat_item. kind != ty:: AssocKind :: Type {
@@ -342,18 +343,18 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
342
343
// This is calculated by taking the intersection of the bounds that each item
343
344
// constrains the GAT with individually.
344
345
let mut new_required_bounds: Option < FxHashSet < ty:: Clause < ' _ > > > = None ;
345
- for item in associated_items {
346
- let item_def_id = item. id . owner_id ;
346
+ for item in associated_items. in_definition_order ( ) {
347
+ let item_def_id = item. def_id . expect_local ( ) ;
347
348
// Skip our own GAT, since it does not constrain itself at all.
348
349
if item_def_id == gat_def_id {
349
350
continue ;
350
351
}
351
352
352
353
let param_env = tcx. param_env ( item_def_id) ;
353
354
354
- let item_required_bounds = match item . kind {
355
+ let item_required_bounds = match tcx . associated_item ( item_def_id ) . kind {
355
356
// In our example, this corresponds to `into_iter` method
356
- hir :: AssocItemKind :: Fn { .. } => {
357
+ ty :: AssocKind :: Fn => {
357
358
// For methods, we check the function signature's return type for any GATs
358
359
// to constrain. In the `into_iter` case, we see that the return type
359
360
// `Self::Iter<'a>` is a GAT we want to gather any potential missing bounds from.
@@ -369,12 +370,12 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
369
370
// We also assume that all of the function signature's parameter types
370
371
// are well formed.
371
372
& sig. inputs ( ) . iter ( ) . copied ( ) . collect ( ) ,
372
- gat_def_id. def_id ,
373
+ gat_def_id,
373
374
gat_generics,
374
375
)
375
376
}
376
377
// In our example, this corresponds to the `Iter` and `Item` associated types
377
- hir :: AssocItemKind :: Type => {
378
+ ty :: AssocKind :: Type => {
378
379
// If our associated item is a GAT with missing bounds, add them to
379
380
// the param-env here. This allows this GAT to propagate missing bounds
380
381
// to other GATs.
@@ -391,11 +392,11 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
391
392
. instantiate_identity_iter_copied ( )
392
393
. collect :: < Vec < _ > > ( ) ,
393
394
& FxIndexSet :: default ( ) ,
394
- gat_def_id. def_id ,
395
+ gat_def_id,
395
396
gat_generics,
396
397
)
397
398
}
398
- hir :: AssocItemKind :: Const => None ,
399
+ ty :: AssocKind :: Const => None ,
399
400
} ;
400
401
401
402
if let Some ( item_required_bounds) = item_required_bounds {
@@ -431,7 +432,12 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
431
432
}
432
433
433
434
for ( gat_def_id, required_bounds) in required_bounds_by_item {
434
- let gat_item_hir = tcx. hir ( ) . expect_trait_item ( gat_def_id. def_id ) ;
435
+ // Don't suggest adding `Self: 'a` to a GAT that can't be named
436
+ if tcx. is_impl_trait_in_trait ( gat_def_id. to_def_id ( ) ) {
437
+ continue ;
438
+ }
439
+
440
+ let gat_item_hir = tcx. hir ( ) . expect_trait_item ( gat_def_id) ;
435
441
debug ! ( ?required_bounds) ;
436
442
let param_env = tcx. param_env ( gat_def_id) ;
437
443
@@ -441,21 +447,16 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe
441
447
ty:: ClauseKind :: RegionOutlives ( ty:: OutlivesPredicate ( a, b) ) => {
442
448
!region_known_to_outlive (
443
449
tcx,
444
- gat_def_id. def_id ,
450
+ gat_def_id,
445
451
param_env,
446
452
& FxIndexSet :: default ( ) ,
447
453
a,
448
454
b,
449
455
)
450
456
}
451
- ty:: ClauseKind :: TypeOutlives ( ty:: OutlivesPredicate ( a, b) ) => !ty_known_to_outlive (
452
- tcx,
453
- gat_def_id. def_id ,
454
- param_env,
455
- & FxIndexSet :: default ( ) ,
456
- a,
457
- b,
458
- ) ,
457
+ ty:: ClauseKind :: TypeOutlives ( ty:: OutlivesPredicate ( a, b) ) => {
458
+ !ty_known_to_outlive ( tcx, gat_def_id, param_env, & FxIndexSet :: default ( ) , a, b)
459
+ }
459
460
_ => bug ! ( "Unexpected ClauseKind" ) ,
460
461
} )
461
462
. map ( |clause| clause. to_string ( ) )
@@ -534,7 +535,7 @@ fn augment_param_env<'tcx>(
534
535
fn gather_gat_bounds < ' tcx , T : TypeFoldable < TyCtxt < ' tcx > > > (
535
536
tcx : TyCtxt < ' tcx > ,
536
537
param_env : ty:: ParamEnv < ' tcx > ,
537
- item_def_id : hir :: OwnerId ,
538
+ item_def_id : LocalDefId ,
538
539
to_check : T ,
539
540
wf_tys : & FxIndexSet < Ty < ' tcx > > ,
540
541
gat_def_id : LocalDefId ,
@@ -567,7 +568,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
567
568
// reflected in a where clause on the GAT itself.
568
569
for ( ty, ty_idx) in & types {
569
570
// In our example, requires that `Self: 'a`
570
- if ty_known_to_outlive ( tcx, item_def_id. def_id , param_env, & wf_tys, * ty, * region_a) {
571
+ if ty_known_to_outlive ( tcx, item_def_id, param_env, & wf_tys, * ty, * region_a) {
571
572
debug ! ( ?ty_idx, ?region_a_idx) ;
572
573
debug ! ( "required clause: {ty} must outlive {region_a}" ) ;
573
574
// Translate into the generic parameters of the GAT. In
@@ -606,14 +607,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
606
607
if matches ! ( * * region_b, ty:: ReStatic | ty:: ReError ( _) ) || region_a == region_b {
607
608
continue ;
608
609
}
609
- if region_known_to_outlive (
610
- tcx,
611
- item_def_id. def_id ,
612
- param_env,
613
- & wf_tys,
614
- * region_a,
615
- * region_b,
616
- ) {
610
+ if region_known_to_outlive ( tcx, item_def_id, param_env, & wf_tys, * region_a, * region_b) {
617
611
debug ! ( ?region_a_idx, ?region_b_idx) ;
618
612
debug ! ( "required clause: {region_a} must outlive {region_b}" ) ;
619
613
// Translate into the generic parameters of the GAT.
@@ -1114,8 +1108,8 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
1114
1108
} ) ;
1115
1109
1116
1110
// Only check traits, don't check trait aliases
1117
- if let hir:: ItemKind :: Trait ( _ , _ , _ , _ , items ) = item. kind {
1118
- check_gat_where_clauses ( tcx, items ) ;
1111
+ if let hir:: ItemKind :: Trait ( .. ) = item. kind {
1112
+ check_gat_where_clauses ( tcx, item . owner_id . def_id ) ;
1119
1113
}
1120
1114
}
1121
1115
0 commit comments