@@ -554,37 +554,29 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
554554 /// like async desugaring.
555555 #[ instrument( level = "debug" , skip( self ) ) ]
556556 fn visit_opaque_ty ( & mut self , opaque : & ' tcx rustc_hir:: OpaqueTy < ' tcx > ) {
557- let mut captures = FxIndexMap :: default ( ) ;
557+ let captures = RefCell :: new ( FxIndexMap :: default ( ) ) ;
558558
559559 let capture_all_in_scope_lifetimes =
560560 opaque_captures_all_in_scope_lifetimes ( self . tcx , opaque) ;
561561 if capture_all_in_scope_lifetimes {
562- let mut create_def_for_duplicated_param = |original_lifetime : LocalDefId , def| {
563- captures. entry ( def) . or_insert_with ( || {
564- let name = self . tcx . item_name ( original_lifetime. to_def_id ( ) ) ;
565- let span = self . tcx . def_span ( original_lifetime) ;
566- let feed = self . tcx . create_def ( opaque. def_id , name, DefKind :: LifetimeParam ) ;
567- feed. def_span ( span) ;
568- feed. def_ident_span ( Some ( span) ) ;
569- feed. def_id ( )
570- } ) ;
562+ let lifetime_ident = |def_id : LocalDefId | {
563+ let name = self . tcx . item_name ( def_id. to_def_id ( ) ) ;
564+ let span = self . tcx . def_span ( def_id) ;
565+ Ident :: new ( name, span)
571566 } ;
572567
573568 // We list scopes outwards, this causes us to see lifetime parameters in reverse
574569 // declaration order. In order to make it consistent with what `generics_of` might
575570 // give, we will reverse the IndexMap after early captures.
576571 let mut scope = self . scope ;
572+ let mut opaque_capture_scopes = vec ! [ ( opaque. def_id, & captures) ] ;
577573 loop {
578574 match * scope {
579575 Scope :: Binder { ref bound_vars, s, .. } => {
580- for ( & original_lifetime, & ( mut def) ) in bound_vars. iter ( ) . rev ( ) {
576+ for ( & original_lifetime, & def) in bound_vars. iter ( ) . rev ( ) {
581577 if let DefKind :: LifetimeParam = self . tcx . def_kind ( original_lifetime) {
582- if let Err ( guar) =
583- self . check_lifetime_is_capturable ( opaque. def_id , def, None )
584- {
585- def = ResolvedArg :: Error ( guar) ;
586- }
587- create_def_for_duplicated_param ( original_lifetime, def) ;
578+ let ident = lifetime_ident ( original_lifetime) ;
579+ self . remap_opaque_captures ( & opaque_capture_scopes, def, ident) ;
588580 }
589581 }
590582 scope = s;
@@ -595,25 +587,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
595587 let parent_generics = self . tcx . generics_of ( parent_item) ;
596588 for param in parent_generics. own_params . iter ( ) . rev ( ) {
597589 if let ty:: GenericParamDefKind :: Lifetime = param. kind {
598- create_def_for_duplicated_param (
599- param. def_id . expect_local ( ) ,
600- ResolvedArg :: EarlyBound ( param. def_id . expect_local ( ) ) ,
601- ) ;
590+ let def = ResolvedArg :: EarlyBound ( param. def_id . expect_local ( ) ) ;
591+ let ident = lifetime_ident ( param. def_id . expect_local ( ) ) ;
592+ self . remap_opaque_captures ( & opaque_capture_scopes, def, ident) ;
602593 }
603594 }
604595 opt_parent_item = parent_generics. parent . and_then ( DefId :: as_local) ;
605596 }
606597 break ;
607598 }
608599
609- Scope :: Opaque { captures : outer_captures, .. } => {
610- for ( _, & duplicated_param) in outer_captures. borrow ( ) . iter ( ) . rev ( ) {
611- create_def_for_duplicated_param (
612- duplicated_param,
613- ResolvedArg :: EarlyBound ( duplicated_param) ,
614- ) ;
615- }
616- break ;
600+ Scope :: Opaque { captures, def_id, s } => {
601+ opaque_capture_scopes. push ( ( def_id, captures) ) ;
602+ scope = s;
617603 }
618604
619605 Scope :: Body { .. } => {
@@ -628,18 +614,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
628614 }
629615 }
630616 }
631- captures. reverse ( ) ;
617+ captures. borrow_mut ( ) . reverse ( ) ;
632618 }
633619
634- let captures = RefCell :: new ( captures) ;
635-
636620 let scope = Scope :: Opaque { captures : & captures, def_id : opaque. def_id , s : self . scope } ;
637621 self . with ( scope, |this| {
638622 let scope = Scope :: TraitRefBoundary { s : this. scope } ;
639623 this. with ( scope, |this| intravisit:: walk_opaque_ty ( this, opaque) )
640624 } ) ;
641625
642626 let captures = captures. into_inner ( ) . into_iter ( ) . collect ( ) ;
627+ debug ! ( ?captures) ;
643628 self . map . opaque_captured_lifetimes . insert ( opaque. def_id , captures) ;
644629 }
645630
@@ -1293,7 +1278,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
12931278 } ;
12941279
12951280 if let Some ( mut def) = result {
1296- def = self . remap_opaque_captures ( opaque_capture_scopes, def, lifetime_ref. ident ) ;
1281+ def = self . remap_opaque_captures ( & opaque_capture_scopes, def, lifetime_ref. ident ) ;
12971282
12981283 if let ResolvedArg :: EarlyBound ( ..) = def {
12991284 // Do not free early-bound regions, only late-bound ones.
@@ -1392,7 +1377,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13921377 & self ,
13931378 opaque_def_id : LocalDefId ,
13941379 lifetime : ResolvedArg ,
1395- span : Option < Span > ,
1380+ capture_span : Span ,
13961381 ) -> Result < ( ) , ErrorGuaranteed > {
13971382 let ResolvedArg :: LateBound ( _, _, lifetime_def_id) = lifetime else { return Ok ( ( ) ) } ;
13981383 let lifetime_hir_id = self . tcx . local_def_id_to_hir_id ( lifetime_def_id) ;
@@ -1412,10 +1397,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
14121397 } ;
14131398
14141399 let decl_span = self . tcx . def_span ( lifetime_def_id) ;
1415- let ( span, label) = if let Some ( span) = span
1416- && span != decl_span
1417- {
1418- ( span, None )
1400+ let ( span, label) = if capture_span != decl_span {
1401+ ( capture_span, None )
14191402 } else {
14201403 let opaque_span = self . tcx . def_span ( opaque_def_id) ;
14211404 ( opaque_span, Some ( opaque_span) )
@@ -1431,19 +1414,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
14311414 Err ( guar)
14321415 }
14331416
1417+ #[ instrument( level = "trace" , skip( self , opaque_capture_scopes) , ret) ]
14341418 fn remap_opaque_captures (
14351419 & self ,
1436- opaque_capture_scopes : Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
1420+ opaque_capture_scopes : & Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
14371421 mut lifetime : ResolvedArg ,
14381422 ident : Ident ,
14391423 ) -> ResolvedArg {
1440- for ( opaque_def_id, captures ) in opaque_capture_scopes. into_iter ( ) . rev ( ) {
1424+ if let Some ( & ( opaque_def_id, _ ) ) = opaque_capture_scopes. last ( ) {
14411425 if let Err ( guar) =
1442- self . check_lifetime_is_capturable ( opaque_def_id, lifetime, Some ( ident. span ) )
1426+ self . check_lifetime_is_capturable ( opaque_def_id, lifetime, ident. span )
14431427 {
1444- return ResolvedArg :: Error ( guar) ;
1428+ lifetime = ResolvedArg :: Error ( guar) ;
14451429 }
1430+ }
14461431
1432+ for & ( opaque_def_id, captures) in opaque_capture_scopes. iter ( ) . rev ( ) {
14471433 let mut captures = captures. borrow_mut ( ) ;
14481434 let remapped = * captures. entry ( lifetime) . or_insert_with ( || {
14491435 let feed = self . tcx . create_def ( opaque_def_id, ident. name , DefKind :: LifetimeParam ) ;
@@ -1976,7 +1962,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
19761962 }
19771963 } ;
19781964
1979- lifetime = self . remap_opaque_captures ( opaque_capture_scopes, lifetime, lifetime_ref. ident ) ;
1965+ lifetime = self . remap_opaque_captures ( & opaque_capture_scopes, lifetime, lifetime_ref. ident ) ;
19801966
19811967 self . insert_lifetime ( lifetime_ref, lifetime) ;
19821968 }
0 commit comments