@@ -270,6 +270,19 @@ enum Scope<'a> {
270270 /// we should use for an early-bound region?
271271 next_early_index : u32 ,
272272
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+
273286 s : ScopeRef < ' a > ,
274287 } ,
275288
@@ -498,6 +511,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
498511 let scope = Scope :: Binder {
499512 lifetimes,
500513 next_early_index,
514+ abstract_type_parent : true ,
501515 s : ROOT_SCOPE ,
502516 } ;
503517 self . with ( scope, |old_scope, this| {
@@ -541,6 +555,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
541555 . collect ( ) ,
542556 s : self . scope ,
543557 next_early_index,
558+ abstract_type_parent : false ,
544559 } ;
545560 self . with ( scope, |old_scope, this| {
546561 // a bare fn has no bounds, so everything
@@ -614,7 +629,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
614629 ref generics,
615630 ref bounds,
616631 } = * 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 ( ) ;
618636 debug ! ( "visit_ty: index = {}" , index) ;
619637
620638 let mut elision = None ;
@@ -638,7 +656,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
638656 s : self . scope
639657 } ;
640658 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+ } ;
642665 this. with ( scope, |_old_scope, this| {
643666 this. visit_generics ( generics) ;
644667 for bound in bounds {
@@ -647,7 +670,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
647670 } ) ;
648671 } ) ;
649672 } 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+ } ;
651679 self . with ( scope, |_old_scope, this| {
652680 this. visit_generics ( generics) ;
653681 for bound in bounds {
@@ -681,7 +709,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
681709 . collect ( ) ;
682710
683711 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+ } ;
685718 self . with ( scope, |_old_scope, this| {
686719 this. visit_generics ( generics) ;
687720 for bound in bounds {
@@ -721,7 +754,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
721754 . collect ( ) ;
722755
723756 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+ } ;
725763 self . with ( scope, |_old_scope, this| {
726764 this. visit_generics ( generics) ;
727765 this. visit_ty ( ty) ;
@@ -792,6 +830,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
792830 . collect ( ) ,
793831 s : self . scope ,
794832 next_early_index,
833+ abstract_type_parent : false ,
795834 } ;
796835 let result = self . with ( scope, |old_scope, this| {
797836 this. check_lifetime_params ( old_scope, & bound_generic_params) ;
@@ -853,6 +892,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
853892 . collect ( ) ,
854893 s : self . scope ,
855894 next_early_index,
895+ abstract_type_parent : false ,
856896 } ;
857897 self . with ( scope, |old_scope, this| {
858898 this. check_lifetime_params ( old_scope, & trait_ref. bound_generic_params ) ;
@@ -1046,6 +1086,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
10461086 ref lifetimes,
10471087 s,
10481088 next_early_index : _,
1089+ abstract_type_parent : _,
10491090 } => {
10501091 // FIXME (#24278): non-hygienic comparison
10511092 if let Some ( def) = lifetimes. get ( & hir:: LifetimeName :: Name ( label) ) {
@@ -1303,32 +1344,49 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
13031344 lifetimes,
13041345 next_early_index,
13051346 s : self . scope ,
1347+ abstract_type_parent : true ,
13061348 } ;
13071349 self . with ( scope, move |old_scope, this| {
13081350 this. check_lifetime_params ( old_scope, & generics. params ) ;
13091351 this. hack ( walk) ; // FIXME(#37666) workaround in place of `walk(this)`
13101352 } ) ;
13111353 }
13121354
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 {
13161356 let mut scope = self . scope ;
13171357 loop {
13181358 match * scope {
13191359 Scope :: Root => return 0 ,
13201360
13211361 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,
13241367
1325- Scope :: Body { s, .. }
1368+ Scope :: Binder { s, .. }
1369+ | Scope :: Body { s, .. }
13261370 | Scope :: Elision { s, .. }
13271371 | Scope :: ObjectLifetimeDefault { s, .. } => scope = s,
13281372 }
13291373 }
13301374 }
13311375
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+
13321390 fn resolve_lifetime_ref ( & mut self , lifetime_ref : & ' tcx hir:: Lifetime ) {
13331391 debug ! ( "resolve_lifetime_ref(lifetime_ref={:?})" , lifetime_ref) ;
13341392 // Walk up the scope chain, tracking the number of fn scopes
@@ -1353,6 +1411,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
13531411 ref lifetimes,
13541412 s,
13551413 next_early_index : _,
1414+ abstract_type_parent : _,
13561415 } => {
13571416 if let Some ( & def) = lifetimes. get ( & lifetime_ref. name ) {
13581417 break Some ( def. shifted ( late_depth) ) ;
@@ -2102,6 +2161,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
21022161 ref lifetimes,
21032162 s,
21042163 next_early_index : _,
2164+ abstract_type_parent : _,
21052165 } => {
21062166 if let Some ( & def) = lifetimes. get ( & lifetime. name ) {
21072167 let node_id = self . tcx . hir . as_local_node_id ( def. id ( ) . unwrap ( ) ) . unwrap ( ) ;
0 commit comments