@@ -462,39 +462,25 @@ pub(super) fn check_opaque<'tcx>(
462
462
463
463
/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
464
464
/// in "inheriting lifetimes".
465
+ #[ instrument( skip( tcx, span) ) ]
465
466
pub ( super ) fn check_opaque_for_inheriting_lifetimes (
466
467
tcx : TyCtxt < ' tcx > ,
467
468
def_id : LocalDefId ,
468
469
span : Span ,
469
470
) {
470
471
let item = tcx. hir ( ) . expect_item ( tcx. hir ( ) . local_def_id_to_hir_id ( def_id) ) ;
471
- debug ! (
472
- "check_opaque_for_inheriting_lifetimes: def_id={:?} span={:?} item={:?}" ,
473
- def_id, span, item
474
- ) ;
475
-
476
- #[ derive( Debug ) ]
477
- struct ProhibitOpaqueVisitor < ' tcx > {
478
- opaque_identity_ty : Ty < ' tcx > ,
479
- generics : & ' tcx ty:: Generics ,
480
- }
472
+ debug ! ( ?item, ?span) ;
481
473
482
- impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for ProhibitOpaqueVisitor < ' tcx > {
483
- type BreakTy = Option < Ty < ' tcx > > ;
484
-
485
- fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
486
- debug ! ( "check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}" , t) ;
487
- if t != self . opaque_identity_ty && t. super_visit_with ( self ) . is_break ( ) {
488
- return ControlFlow :: Break ( Some ( t) ) ;
489
- }
490
- ControlFlow :: CONTINUE
491
- }
474
+ struct FoundParentLifetime ;
475
+ struct FindParentLifetimeVisitor < ' tcx > ( & ' tcx ty:: Generics ) ;
476
+ impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for FindParentLifetimeVisitor < ' tcx > {
477
+ type BreakTy = FoundParentLifetime ;
492
478
493
479
fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
494
- debug ! ( "check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}" , r) ;
480
+ debug ! ( "FindParentLifetimeVisitor: r={:?}" , r) ;
495
481
if let RegionKind :: ReEarlyBound ( ty:: EarlyBoundRegion { index, .. } ) = r {
496
- if * index < self . generics . parent_count as u32 {
497
- return ControlFlow :: Break ( None ) ;
482
+ if * index < self . 0 . parent_count as u32 {
483
+ return ControlFlow :: Break ( FoundParentLifetime ) ;
498
484
} else {
499
485
return ControlFlow :: CONTINUE ;
500
486
}
@@ -505,7 +491,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
505
491
506
492
fn visit_const ( & mut self , c : & ' tcx ty:: Const < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
507
493
if let ty:: ConstKind :: Unevaluated ( ..) = c. val {
508
- // FIXME(#72219) We currenctly don't detect lifetimes within substs
494
+ // FIXME(#72219) We currently don't detect lifetimes within substs
509
495
// which would violate this check. Even though the particular substitution is not used
510
496
// within the const, this should still be fixed.
511
497
return ControlFlow :: CONTINUE ;
@@ -514,6 +500,26 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
514
500
}
515
501
}
516
502
503
+ #[ derive( Debug ) ]
504
+ struct ProhibitOpaqueVisitor < ' tcx > {
505
+ opaque_identity_ty : Ty < ' tcx > ,
506
+ generics : & ' tcx ty:: Generics ,
507
+ }
508
+
509
+ impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for ProhibitOpaqueVisitor < ' tcx > {
510
+ type BreakTy = Ty < ' tcx > ;
511
+
512
+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
513
+ debug ! ( "check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}" , t) ;
514
+ if t == self . opaque_identity_ty {
515
+ ControlFlow :: CONTINUE
516
+ } else {
517
+ t. super_visit_with ( & mut FindParentLifetimeVisitor ( self . generics ) )
518
+ . map_break ( |FoundParentLifetime | t)
519
+ }
520
+ }
521
+ }
522
+
517
523
if let ItemKind :: OpaqueTy ( hir:: OpaqueTy {
518
524
origin : hir:: OpaqueTyOrigin :: AsyncFn | hir:: OpaqueTyOrigin :: FnReturn ,
519
525
..
@@ -555,14 +561,12 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
555
561
556
562
if let Ok ( snippet) = tcx. sess . source_map ( ) . span_to_snippet ( span) {
557
563
if snippet == "Self" {
558
- if let Some ( ty) = ty {
559
- err. span_suggestion (
560
- span,
561
- "consider spelling out the type instead" ,
562
- format ! ( "{:?}" , ty) ,
563
- Applicability :: MaybeIncorrect ,
564
- ) ;
565
- }
564
+ err. span_suggestion (
565
+ span,
566
+ "consider spelling out the type instead" ,
567
+ format ! ( "{:?}" , ty) ,
568
+ Applicability :: MaybeIncorrect ,
569
+ ) ;
566
570
}
567
571
}
568
572
err. emit ( ) ;
0 commit comments