@@ -557,37 +557,29 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
557557 /// like async desugaring.
558558 #[ instrument( level = "debug" , skip( self ) ) ]
559559 fn visit_opaque_ty ( & mut self , opaque : & ' tcx rustc_hir:: OpaqueTy < ' tcx > ) {
560- let mut captures = FxIndexMap :: default ( ) ;
560+ let captures = RefCell :: new ( FxIndexMap :: default ( ) ) ;
561561
562562 let capture_all_in_scope_lifetimes =
563563 opaque_captures_all_in_scope_lifetimes ( self . tcx , opaque) ;
564564 if capture_all_in_scope_lifetimes {
565- let mut create_def_for_duplicated_param = |original_lifetime : LocalDefId , def| {
566- captures. entry ( def) . or_insert_with ( || {
567- let name = self . tcx . item_name ( original_lifetime. to_def_id ( ) ) ;
568- let span = self . tcx . def_span ( original_lifetime) ;
569- let feed = self . tcx . create_def ( opaque. def_id , name, DefKind :: LifetimeParam ) ;
570- feed. def_span ( span) ;
571- feed. def_ident_span ( Some ( span) ) ;
572- feed. def_id ( )
573- } ) ;
565+ let lifetime_ident = |def_id : LocalDefId | {
566+ let name = self . tcx . item_name ( def_id. to_def_id ( ) ) ;
567+ let span = self . tcx . def_span ( def_id) ;
568+ Ident :: new ( name, span)
574569 } ;
575570
576571 // We list scopes outwards, this causes us to see lifetime parameters in reverse
577572 // declaration order. In order to make it consistent with what `generics_of` might
578573 // give, we will reverse the IndexMap after early captures.
579574 let mut scope = self . scope ;
575+ let mut opaque_capture_scopes = vec ! [ ( opaque. def_id, & captures) ] ;
580576 loop {
581577 match * scope {
582578 Scope :: Binder { ref bound_vars, s, .. } => {
583- for ( & original_lifetime, & ( mut def) ) in bound_vars. iter ( ) . rev ( ) {
579+ for ( & original_lifetime, & def) in bound_vars. iter ( ) . rev ( ) {
584580 if let DefKind :: LifetimeParam = self . tcx . def_kind ( original_lifetime) {
585- if let Err ( guar) =
586- self . check_lifetime_is_capturable ( opaque. def_id , def, None )
587- {
588- def = ResolvedArg :: Error ( guar) ;
589- }
590- create_def_for_duplicated_param ( original_lifetime, def) ;
581+ let ident = lifetime_ident ( original_lifetime) ;
582+ self . remap_opaque_captures ( & opaque_capture_scopes, def, ident) ;
591583 }
592584 }
593585 scope = s;
@@ -598,25 +590,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
598590 let parent_generics = self . tcx . generics_of ( parent_item) ;
599591 for param in parent_generics. own_params . iter ( ) . rev ( ) {
600592 if let ty:: GenericParamDefKind :: Lifetime = param. kind {
601- create_def_for_duplicated_param (
602- param. def_id . expect_local ( ) ,
603- ResolvedArg :: EarlyBound ( param. def_id . expect_local ( ) ) ,
604- ) ;
593+ let def = ResolvedArg :: EarlyBound ( param. def_id . expect_local ( ) ) ;
594+ let ident = lifetime_ident ( param. def_id . expect_local ( ) ) ;
595+ self . remap_opaque_captures ( & opaque_capture_scopes, def, ident) ;
605596 }
606597 }
607598 opt_parent_item = parent_generics. parent . and_then ( DefId :: as_local) ;
608599 }
609600 break ;
610601 }
611602
612- Scope :: Opaque { captures : outer_captures, .. } => {
613- for ( _, & duplicated_param) in outer_captures. borrow ( ) . iter ( ) . rev ( ) {
614- create_def_for_duplicated_param (
615- duplicated_param,
616- ResolvedArg :: EarlyBound ( duplicated_param) ,
617- ) ;
618- }
619- break ;
603+ Scope :: Opaque { captures, def_id, s } => {
604+ opaque_capture_scopes. push ( ( def_id, captures) ) ;
605+ scope = s;
620606 }
621607
622608 Scope :: Body { .. } => {
@@ -631,18 +617,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
631617 }
632618 }
633619 }
634- captures. reverse ( ) ;
620+ captures. borrow_mut ( ) . reverse ( ) ;
635621 }
636622
637- let captures = RefCell :: new ( captures) ;
638-
639623 let scope = Scope :: Opaque { captures : & captures, def_id : opaque. def_id , s : self . scope } ;
640624 self . with ( scope, |this| {
641625 let scope = Scope :: TraitRefBoundary { s : this. scope } ;
642626 this. with ( scope, |this| intravisit:: walk_opaque_ty ( this, opaque) )
643627 } ) ;
644628
645629 let captures = captures. into_inner ( ) . into_iter ( ) . collect ( ) ;
630+ debug ! ( ?captures) ;
646631 self . map . opaque_captured_lifetimes . insert ( opaque. def_id , captures) ;
647632 }
648633
@@ -1297,7 +1282,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
12971282 } ;
12981283
12991284 if let Some ( mut def) = result {
1300- def = self . remap_opaque_captures ( opaque_capture_scopes, def, lifetime_ref. ident ) ;
1285+ def = self . remap_opaque_captures ( & opaque_capture_scopes, def, lifetime_ref. ident ) ;
13011286
13021287 if let ResolvedArg :: EarlyBound ( ..) = def {
13031288 // Do not free early-bound regions, only late-bound ones.
@@ -1396,7 +1381,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13961381 & self ,
13971382 opaque_def_id : LocalDefId ,
13981383 lifetime : ResolvedArg ,
1399- span : Option < Span > ,
1384+ capture_span : Span ,
14001385 ) -> Result < ( ) , ErrorGuaranteed > {
14011386 let ResolvedArg :: LateBound ( _, _, lifetime_def_id) = lifetime else { return Ok ( ( ) ) } ;
14021387 let lifetime_hir_id = self . tcx . local_def_id_to_hir_id ( lifetime_def_id) ;
@@ -1416,10 +1401,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
14161401 } ;
14171402
14181403 let decl_span = self . tcx . def_span ( lifetime_def_id) ;
1419- let ( span, label) = if let Some ( span) = span
1420- && span != decl_span
1421- {
1422- ( span, None )
1404+ let ( span, label) = if capture_span != decl_span {
1405+ ( capture_span, None )
14231406 } else {
14241407 let opaque_span = self . tcx . def_span ( opaque_def_id) ;
14251408 ( opaque_span, Some ( opaque_span) )
@@ -1435,19 +1418,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
14351418 Err ( guar)
14361419 }
14371420
1421+ #[ instrument( level = "trace" , skip( self , opaque_capture_scopes) , ret) ]
14381422 fn remap_opaque_captures (
14391423 & self ,
1440- opaque_capture_scopes : Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
1424+ opaque_capture_scopes : & Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
14411425 mut lifetime : ResolvedArg ,
14421426 ident : Ident ,
14431427 ) -> ResolvedArg {
1444- for ( opaque_def_id, captures ) in opaque_capture_scopes. into_iter ( ) . rev ( ) {
1428+ if let Some ( & ( opaque_def_id, _ ) ) = opaque_capture_scopes. last ( ) {
14451429 if let Err ( guar) =
1446- self . check_lifetime_is_capturable ( opaque_def_id, lifetime, Some ( ident. span ) )
1430+ self . check_lifetime_is_capturable ( opaque_def_id, lifetime, ident. span )
14471431 {
1448- return ResolvedArg :: Error ( guar) ;
1432+ lifetime = ResolvedArg :: Error ( guar) ;
14491433 }
1434+ }
14501435
1436+ for & ( opaque_def_id, captures) in opaque_capture_scopes. iter ( ) . rev ( ) {
14511437 let mut captures = captures. borrow_mut ( ) ;
14521438 let remapped = * captures. entry ( lifetime) . or_insert_with ( || {
14531439 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