@@ -554,37 +554,29 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
554
554
/// like async desugaring.
555
555
#[ instrument( level = "debug" , skip( self ) ) ]
556
556
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 ( ) ) ;
558
558
559
559
let capture_all_in_scope_lifetimes =
560
560
opaque_captures_all_in_scope_lifetimes ( self . tcx , opaque) ;
561
561
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)
571
566
} ;
572
567
573
568
// We list scopes outwards, this causes us to see lifetime parameters in reverse
574
569
// declaration order. In order to make it consistent with what `generics_of` might
575
570
// give, we will reverse the IndexMap after early captures.
576
571
let mut scope = self . scope ;
572
+ let mut opaque_capture_scopes = vec ! [ ( opaque. def_id, & captures) ] ;
577
573
loop {
578
574
match * scope {
579
575
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 ( ) {
581
577
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) ;
588
580
}
589
581
}
590
582
scope = s;
@@ -595,25 +587,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
595
587
let parent_generics = self . tcx . generics_of ( parent_item) ;
596
588
for param in parent_generics. own_params . iter ( ) . rev ( ) {
597
589
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) ;
602
593
}
603
594
}
604
595
opt_parent_item = parent_generics. parent . and_then ( DefId :: as_local) ;
605
596
}
606
597
break ;
607
598
}
608
599
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;
617
603
}
618
604
619
605
Scope :: Body { .. } => {
@@ -628,18 +614,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
628
614
}
629
615
}
630
616
}
631
- captures. reverse ( ) ;
617
+ captures. borrow_mut ( ) . reverse ( ) ;
632
618
}
633
619
634
- let captures = RefCell :: new ( captures) ;
635
-
636
620
let scope = Scope :: Opaque { captures : & captures, def_id : opaque. def_id , s : self . scope } ;
637
621
self . with ( scope, |this| {
638
622
let scope = Scope :: TraitRefBoundary { s : this. scope } ;
639
623
this. with ( scope, |this| intravisit:: walk_opaque_ty ( this, opaque) )
640
624
} ) ;
641
625
642
626
let captures = captures. into_inner ( ) . into_iter ( ) . collect ( ) ;
627
+ debug ! ( ?captures) ;
643
628
self . map . opaque_captured_lifetimes . insert ( opaque. def_id , captures) ;
644
629
}
645
630
@@ -1293,7 +1278,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1293
1278
} ;
1294
1279
1295
1280
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 ) ;
1297
1282
1298
1283
if let ResolvedArg :: EarlyBound ( ..) = def {
1299
1284
// Do not free early-bound regions, only late-bound ones.
@@ -1392,7 +1377,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1392
1377
& self ,
1393
1378
opaque_def_id : LocalDefId ,
1394
1379
lifetime : ResolvedArg ,
1395
- span : Option < Span > ,
1380
+ capture_span : Span ,
1396
1381
) -> Result < ( ) , ErrorGuaranteed > {
1397
1382
let ResolvedArg :: LateBound ( _, _, lifetime_def_id) = lifetime else { return Ok ( ( ) ) } ;
1398
1383
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> {
1412
1397
} ;
1413
1398
1414
1399
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 )
1419
1402
} else {
1420
1403
let opaque_span = self . tcx . def_span ( opaque_def_id) ;
1421
1404
( opaque_span, Some ( opaque_span) )
@@ -1431,19 +1414,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
1431
1414
Err ( guar)
1432
1415
}
1433
1416
1417
+ #[ instrument( level = "trace" , skip( self , opaque_capture_scopes) , ret) ]
1434
1418
fn remap_opaque_captures (
1435
1419
& self ,
1436
- opaque_capture_scopes : Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
1420
+ opaque_capture_scopes : & Vec < ( LocalDefId , & RefCell < FxIndexMap < ResolvedArg , LocalDefId > > ) > ,
1437
1421
mut lifetime : ResolvedArg ,
1438
1422
ident : Ident ,
1439
1423
) -> 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 ( ) {
1441
1425
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 )
1443
1427
{
1444
- return ResolvedArg :: Error ( guar) ;
1428
+ lifetime = ResolvedArg :: Error ( guar) ;
1445
1429
}
1430
+ }
1446
1431
1432
+ for & ( opaque_def_id, captures) in opaque_capture_scopes. iter ( ) . rev ( ) {
1447
1433
let mut captures = captures. borrow_mut ( ) ;
1448
1434
let remapped = * captures. entry ( lifetime) . or_insert_with ( || {
1449
1435
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