@@ -492,6 +492,7 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
492492    } ; 
493493
494494    let  mut  expected_captures = UnordSet :: default ( ) ; 
495+     let  mut  shadowed_captures = UnordSet :: default ( ) ; 
495496    let  mut  seen_params = UnordMap :: default ( ) ; 
496497    let  mut  prev_non_lifetime_param = None ; 
497498    for  arg in  precise_capturing_args { 
@@ -530,6 +531,21 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
530531        match  tcx. named_bound_var ( hir_id)  { 
531532            Some ( ResolvedArg :: EarlyBound ( def_id) )  => { 
532533                expected_captures. insert ( def_id) ; 
534+ 
535+                 // Make sure we allow capturing these lifetimes through `Self` and 
536+                 // `T::Assoc` projection syntax, too. These will occur when we only 
537+                 // see lifetimes are captured after hir-lowering -- this aligns with 
538+                 // the cases that were stabilized with the `impl_trait_projection` 
539+                 // feature -- see <https://github.com/rust-lang/rust/pull/115659>. 
540+                 if  let  DefKind :: LifetimeParam  = tcx. def_kind ( def_id) 
541+                     && let  ty:: ReEarlyParam ( ty:: EarlyParamRegion  {  def_id,  .. } ) 
542+                     | ty:: ReLateParam ( ty:: LateParamRegion  { 
543+                         bound_region :  ty:: BoundRegionKind :: BrNamed ( def_id,  _) , 
544+                         ..
545+                     } )  = * tcx. map_opaque_lifetime_to_parent_lifetime ( def_id. expect_local ( ) ) 
546+                 { 
547+                     shadowed_captures. insert ( def_id) ; 
548+                 } 
533549            } 
534550            _ => { 
535551                tcx. dcx ( ) . span_delayed_bug ( 
@@ -555,23 +571,30 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
555571                ) ; 
556572                continue ; 
557573            } 
574+             // If a param is shadowed by a early-bound (duplicated) lifetime, then 
575+             // it may or may not be captured as invariant, depending on if it shows 
576+             // up through `Self` or `T::Assoc` syntax. 
577+             if  shadowed_captures. contains ( & param. def_id )  { 
578+                 continue ; 
579+             } 
558580
559581            match  param. kind  { 
560582                ty:: GenericParamDefKind :: Lifetime  => { 
561583                    // Check if the lifetime param was captured but isn't named in the precise captures list. 
562584                    if  variances[ param. index  as  usize ]  == ty:: Invariant  { 
563-                         let  param_span =
564-                             if  let  ty:: ReEarlyParam ( ty:: EarlyParamRegion  {  def_id,  .. } ) 
585+                         let  param_span = if  let  DefKind :: OpaqueTy  =
586+                             tcx. def_kind ( tcx. parent ( param. def_id ) ) 
587+                             && let  ty:: ReEarlyParam ( ty:: EarlyParamRegion  {  def_id,  .. } ) 
565588                            | ty:: ReLateParam ( ty:: LateParamRegion  { 
566589                                bound_region :  ty:: BoundRegionKind :: BrNamed ( def_id,  _) , 
567590                                ..
568591                            } )  = * tcx
569592                                . map_opaque_lifetime_to_parent_lifetime ( param. def_id . expect_local ( ) ) 
570-                              { 
571-                                  Some ( tcx. def_span ( def_id) ) 
572-                              }  else  { 
573-                                  None 
574-                              } ; 
593+                         { 
594+                             Some ( tcx. def_span ( def_id) ) 
595+                         }  else  { 
596+                             None 
597+                         } ; 
575598                        // FIXME(precise_capturing): Structured suggestion for this would be useful 
576599                        tcx. dcx ( ) . emit_err ( errors:: LifetimeNotCaptured  { 
577600                            use_span :  tcx. def_span ( param. def_id ) , 
0 commit comments