@@ -557,37 +557,29 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
557
557
/// like async desugaring.
558
558
#[ instrument( level = "debug" , skip( self ) ) ]
559
559
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 ( ) ) ;
561
561
562
562
let capture_all_in_scope_lifetimes =
563
563
opaque_captures_all_in_scope_lifetimes ( self . tcx , opaque) ;
564
564
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)
574
569
} ;
575
570
576
571
// We list scopes outwards, this causes us to see lifetime parameters in reverse
577
572
// declaration order. In order to make it consistent with what `generics_of` might
578
573
// give, we will reverse the IndexMap after early captures.
579
574
let mut scope = self . scope ;
575
+ let mut opaque_capture_scopes = vec ! [ ( opaque. def_id, & captures) ] ;
580
576
loop {
581
577
match * scope {
582
578
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 ( ) {
584
580
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) ;
591
583
}
592
584
}
593
585
scope = s;
@@ -598,25 +590,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
598
590
let parent_generics = self . tcx . generics_of ( parent_item) ;
599
591
for param in parent_generics. own_params . iter ( ) . rev ( ) {
600
592
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) ;
605
596
}
606
597
}
607
598
opt_parent_item = parent_generics. parent . and_then ( DefId :: as_local) ;
608
599
}
609
600
break ;
610
601
}
611
602
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;
620
606
}
621
607
622
608
Scope :: Body { .. } => {
@@ -631,18 +617,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
631
617
}
632
618
}
633
619
}
634
- captures. reverse ( ) ;
620
+ captures. borrow_mut ( ) . reverse ( ) ;
635
621
}
636
622
637
- let captures = RefCell :: new ( captures) ;
638
-
639
623
let scope = Scope :: Opaque { captures : & captures, def_id : opaque. def_id , s : self . scope } ;
640
624
self . with ( scope, |this| {
641
625
let scope = Scope :: TraitRefBoundary { s : this. scope } ;
642
626
this. with ( scope, |this| intravisit:: walk_opaque_ty ( this, opaque) )
643
627
} ) ;
644
628
645
629
let captures = captures. into_inner ( ) . into_iter ( ) . collect ( ) ;
630
+ debug ! ( ?captures) ;
646
631
self . map . opaque_captured_lifetimes . insert ( opaque. def_id , captures) ;
647
632
}
648
633
@@ -1297,7 +1282,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1297
1282
} ;
1298
1283
1299
1284
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 ) ;
1301
1286
1302
1287
if let ResolvedArg :: EarlyBound ( ..) = def {
1303
1288
// Do not free early-bound regions, only late-bound ones.
@@ -1396,7 +1381,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1396
1381
& self ,
1397
1382
opaque_def_id : LocalDefId ,
1398
1383
lifetime : ResolvedArg ,
1399
- span : Option < Span > ,
1384
+ capture_span : Span ,
1400
1385
) -> Result < ( ) , ErrorGuaranteed > {
1401
1386
let ResolvedArg :: LateBound ( _, _, lifetime_def_id) = lifetime else { return Ok ( ( ) ) } ;
1402
1387
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> {
1416
1401
} ;
1417
1402
1418
1403
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 )
1423
1406
} else {
1424
1407
let opaque_span = self . tcx . def_span ( opaque_def_id) ;
1425
1408
( opaque_span, Some ( opaque_span) )
@@ -1435,19 +1418,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1435
1418
Err ( guar)
1436
1419
}
1437
1420
1421
+ #[ instrument( level = "trace" , skip( self , opaque_capture_scopes) , ret) ]
1438
1422
fn remap_opaque_captures (
1439
1423
& self ,
1440
- opaque_capture_scopes : Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
1424
+ opaque_capture_scopes : & Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
1441
1425
mut lifetime : ResolvedArg ,
1442
1426
ident : Ident ,
1443
1427
) -> 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 ( ) {
1445
1429
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 )
1447
1431
{
1448
- return ResolvedArg :: Error ( guar) ;
1432
+ lifetime = ResolvedArg :: Error ( guar) ;
1449
1433
}
1434
+ }
1450
1435
1436
+ for & ( opaque_def_id, captures) in opaque_capture_scopes. iter ( ) . rev ( ) {
1451
1437
let mut captures = captures. borrow_mut ( ) ;
1452
1438
let remapped = * captures. entry ( lifetime) . or_insert_with ( || {
1453
1439
let feed = self . tcx . create_def ( opaque_def_id, ident. name , DefKind :: LifetimeParam ) ;
@@ -1976,7 +1962,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1976
1962
}
1977
1963
} ;
1978
1964
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 ) ;
1980
1966
1981
1967
self . insert_lifetime ( lifetime_ref, lifetime) ;
1982
1968
}
0 commit comments