@@ -270,6 +270,19 @@ enum Scope<'a> {
270
270
/// we should use for an early-bound region?
271
271
next_early_index : u32 ,
272
272
273
+ /// Whether or not this binder would serve as the parent
274
+ /// binder for abstract types introduced within. For example:
275
+ ///
276
+ /// fn foo<'a>() -> impl for<'b> Trait<Item = impl Trait2<'a>>
277
+ ///
278
+ /// Here, the abstract types we create for the `impl Trait`
279
+ /// and `impl Trait2` references will both have the `foo` item
280
+ /// as their parent. When we get to `impl Trait2`, we find
281
+ /// that it is nested within the `for<>` binder -- this flag
282
+ /// allows us to skip that when looking for the parent binder
283
+ /// of the resulting abstract type.
284
+ abstract_type_parent : bool ,
285
+
273
286
s : ScopeRef < ' a > ,
274
287
} ,
275
288
@@ -498,6 +511,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
498
511
let scope = Scope :: Binder {
499
512
lifetimes,
500
513
next_early_index,
514
+ abstract_type_parent : true ,
501
515
s : ROOT_SCOPE ,
502
516
} ;
503
517
self . with ( scope, |old_scope, this| {
@@ -541,6 +555,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
541
555
. collect ( ) ,
542
556
s : self . scope ,
543
557
next_early_index,
558
+ abstract_type_parent : false ,
544
559
} ;
545
560
self . with ( scope, |old_scope, this| {
546
561
// a bare fn has no bounds, so everything
@@ -614,7 +629,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
614
629
ref generics,
615
630
ref bounds,
616
631
} = * exist_ty;
617
- let mut index = self . next_early_index ( ) ;
632
+
633
+ // We want to start our early-bound indices at the end of the parent scope,
634
+ // not including any parent `impl Trait`s.
635
+ let mut index = self . next_early_index_for_abstract_type ( ) ;
618
636
debug ! ( "visit_ty: index = {}" , index) ;
619
637
620
638
let mut elision = None ;
@@ -638,7 +656,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
638
656
s : self . scope
639
657
} ;
640
658
self . with ( scope, |_old_scope, this| {
641
- let scope = Scope :: Binder { lifetimes, next_early_index, s : this. scope } ;
659
+ let scope = Scope :: Binder {
660
+ lifetimes,
661
+ next_early_index,
662
+ s : this. scope ,
663
+ abstract_type_parent : false ,
664
+ } ;
642
665
this. with ( scope, |_old_scope, this| {
643
666
this. visit_generics ( generics) ;
644
667
for bound in bounds {
@@ -647,7 +670,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
647
670
} ) ;
648
671
} ) ;
649
672
} else {
650
- let scope = Scope :: Binder { lifetimes, next_early_index, s : self . scope } ;
673
+ let scope = Scope :: Binder {
674
+ lifetimes,
675
+ next_early_index,
676
+ s : self . scope ,
677
+ abstract_type_parent : false ,
678
+ } ;
651
679
self . with ( scope, |_old_scope, this| {
652
680
this. visit_generics ( generics) ;
653
681
for bound in bounds {
@@ -681,7 +709,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
681
709
. collect ( ) ;
682
710
683
711
let next_early_index = index + generics. ty_params ( ) . count ( ) as u32 ;
684
- let scope = Scope :: Binder { lifetimes, next_early_index, s : self . scope } ;
712
+ let scope = Scope :: Binder {
713
+ lifetimes,
714
+ next_early_index,
715
+ s : self . scope ,
716
+ abstract_type_parent : true ,
717
+ } ;
685
718
self . with ( scope, |_old_scope, this| {
686
719
this. visit_generics ( generics) ;
687
720
for bound in bounds {
@@ -721,7 +754,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
721
754
. collect ( ) ;
722
755
723
756
let next_early_index = index + generics. ty_params ( ) . count ( ) as u32 ;
724
- let scope = Scope :: Binder { lifetimes, next_early_index, s : self . scope } ;
757
+ let scope = Scope :: Binder {
758
+ lifetimes,
759
+ next_early_index,
760
+ s : self . scope ,
761
+ abstract_type_parent : true ,
762
+ } ;
725
763
self . with ( scope, |_old_scope, this| {
726
764
this. visit_generics ( generics) ;
727
765
this. visit_ty ( ty) ;
@@ -792,6 +830,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
792
830
. collect ( ) ,
793
831
s : self . scope ,
794
832
next_early_index,
833
+ abstract_type_parent : false ,
795
834
} ;
796
835
let result = self . with ( scope, |old_scope, this| {
797
836
this. check_lifetime_params ( old_scope, & bound_generic_params) ;
@@ -853,6 +892,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
853
892
. collect ( ) ,
854
893
s : self . scope ,
855
894
next_early_index,
895
+ abstract_type_parent : false ,
856
896
} ;
857
897
self . with ( scope, |old_scope, this| {
858
898
this. check_lifetime_params ( old_scope, & trait_ref. bound_generic_params ) ;
@@ -1046,6 +1086,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
1046
1086
ref lifetimes,
1047
1087
s,
1048
1088
next_early_index : _,
1089
+ abstract_type_parent : _,
1049
1090
} => {
1050
1091
// FIXME (#24278): non-hygienic comparison
1051
1092
if let Some ( def) = lifetimes. get ( & hir:: LifetimeName :: Name ( label) ) {
@@ -1303,32 +1344,49 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1303
1344
lifetimes,
1304
1345
next_early_index,
1305
1346
s : self . scope ,
1347
+ abstract_type_parent : true ,
1306
1348
} ;
1307
1349
self . with ( scope, move |old_scope, this| {
1308
1350
this. check_lifetime_params ( old_scope, & generics. params ) ;
1309
1351
this. hack ( walk) ; // FIXME(#37666) workaround in place of `walk(this)`
1310
1352
} ) ;
1311
1353
}
1312
1354
1313
- /// Returns the next index one would use for an early-bound-region
1314
- /// if extending the current scope.
1315
- fn next_early_index ( & self ) -> u32 {
1355
+ fn next_early_index_helper ( & self , only_abstract_type_parent : bool ) -> u32 {
1316
1356
let mut scope = self . scope ;
1317
1357
loop {
1318
1358
match * scope {
1319
1359
Scope :: Root => return 0 ,
1320
1360
1321
1361
Scope :: Binder {
1322
- next_early_index, ..
1323
- } => return next_early_index,
1362
+ next_early_index,
1363
+ abstract_type_parent,
1364
+ ..
1365
+ } if ( !only_abstract_type_parent || abstract_type_parent)
1366
+ => return next_early_index,
1324
1367
1325
- Scope :: Body { s, .. }
1368
+ Scope :: Binder { s, .. }
1369
+ | Scope :: Body { s, .. }
1326
1370
| Scope :: Elision { s, .. }
1327
1371
| Scope :: ObjectLifetimeDefault { s, .. } => scope = s,
1328
1372
}
1329
1373
}
1330
1374
}
1331
1375
1376
+ /// Returns the next index one would use for an early-bound-region
1377
+ /// if extending the current scope.
1378
+ fn next_early_index ( & self ) -> u32 {
1379
+ self . next_early_index_helper ( true )
1380
+ }
1381
+
1382
+ /// Returns the next index one would use for an `impl Trait` that
1383
+ /// is being converted into an `abstract type`. This will be the
1384
+ /// next early index from the enclosing item, for the most
1385
+ /// part. See the `abstract_type_parent` field for more info.
1386
+ fn next_early_index_for_abstract_type ( & self ) -> u32 {
1387
+ self . next_early_index_helper ( false )
1388
+ }
1389
+
1332
1390
fn resolve_lifetime_ref ( & mut self , lifetime_ref : & ' tcx hir:: Lifetime ) {
1333
1391
debug ! ( "resolve_lifetime_ref(lifetime_ref={:?})" , lifetime_ref) ;
1334
1392
// Walk up the scope chain, tracking the number of fn scopes
@@ -1353,6 +1411,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
1353
1411
ref lifetimes,
1354
1412
s,
1355
1413
next_early_index : _,
1414
+ abstract_type_parent : _,
1356
1415
} => {
1357
1416
if let Some ( & def) = lifetimes. get ( & lifetime_ref. name ) {
1358
1417
break Some ( def. shifted ( late_depth) ) ;
@@ -2102,6 +2161,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2102
2161
ref lifetimes,
2103
2162
s,
2104
2163
next_early_index : _,
2164
+ abstract_type_parent : _,
2105
2165
} => {
2106
2166
if let Some ( & def) = lifetimes. get ( & lifetime. name ) {
2107
2167
let node_id = self . tcx . hir . as_local_node_id ( def. id ( ) . unwrap ( ) ) . unwrap ( ) ;
0 commit comments