@@ -89,9 +89,12 @@ struct LifetimeContext<'a, 'tcx: 'a> {
89
89
90
90
#[ derive( PartialEq , Debug ) ]
91
91
enum ScopeChain < ' a > {
92
- /// EarlyScope(['a, 'b, ...], s) extends s with early-bound
93
- /// lifetimes.
94
- EarlyScope ( & ' a [ hir:: LifetimeDef ] , Scope < ' a > ) ,
92
+ /// EarlyScope(['a, 'b, ...], start, s) extends s with early-bound
93
+ /// lifetimes, with consecutive parameter indices from `start`.
94
+ /// That is, 'a has index `start`, 'b has index `start + 1`, etc.
95
+ /// Indices before `start` correspond to other generic parameters
96
+ /// of a parent item (trait/impl of a method), or `Self` in traits.
97
+ EarlyScope ( & ' a [ hir:: LifetimeDef ] , u32 , Scope < ' a > ) ,
95
98
/// LateScope(['a, 'b, ...], s) extends s with late-bound
96
99
/// lifetimes introduced by the declaration binder_id.
97
100
LateScope ( & ' a [ hir:: LifetimeDef ] , Scope < ' a > ) ,
@@ -157,7 +160,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for LifetimeContext<'a, 'tcx> {
157
160
hir:: ItemImpl ( _, _, ref generics, _, _, _) => {
158
161
// These kinds of items have only early bound lifetime parameters.
159
162
let lifetimes = & generics. lifetimes ;
160
- this. with ( EarlyScope ( lifetimes, & ROOT_SCOPE ) , |old_scope, this| {
163
+ let start = if let hir:: ItemTrait ( ..) = item. node {
164
+ 1 // Self comes before lifetimes
165
+ } else {
166
+ 0
167
+ } ;
168
+ this. with ( EarlyScope ( lifetimes, start, & ROOT_SCOPE ) , |old_scope, this| {
161
169
this. check_lifetime_defs ( old_scope, lifetimes) ;
162
170
intravisit:: walk_item ( this, item) ;
163
171
} ) ;
@@ -461,7 +469,7 @@ fn extract_labels(ctxt: &mut LifetimeContext, b: &hir::Block) {
461
469
FnScope { s, .. } => { scope = s; }
462
470
RootScope => { return ; }
463
471
464
- EarlyScope ( lifetimes, s) |
472
+ EarlyScope ( lifetimes, _ , s) |
465
473
LateScope ( lifetimes, s) => {
466
474
for lifetime_def in lifetimes {
467
475
// FIXME (#24278): non-hygienic comparison
@@ -566,8 +574,24 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
566
574
. cloned ( )
567
575
. partition ( |l| self . map . late_bound . contains_key ( & l. lifetime . id ) ) ;
568
576
577
+ // Find the start of nested early scopes, e.g. in methods.
578
+ let mut start = 0 ;
579
+ if let EarlyScope ( ..) = * self . scope {
580
+ let parent = self . hir_map . expect_item ( self . hir_map . get_parent ( fn_id) ) ;
581
+ if let hir:: ItemTrait ( ..) = parent. node {
582
+ start += 1 ; // Self comes first.
583
+ }
584
+ match parent. node {
585
+ hir:: ItemTrait ( _, ref generics, _, _) |
586
+ hir:: ItemImpl ( _, _, ref generics, _, _, _) => {
587
+ start += generics. lifetimes . len ( ) + generics. ty_params . len ( ) ;
588
+ }
589
+ _ => { }
590
+ }
591
+ }
592
+
569
593
let this = self ;
570
- this. with ( EarlyScope ( & early, this. scope ) , move |old_scope, this| {
594
+ this. with ( EarlyScope ( & early, start as u32 , this. scope ) , move |old_scope, this| {
571
595
this. with ( LateScope ( & late, this. scope ) , move |_, this| {
572
596
this. check_lifetime_defs ( old_scope, & generics. lifetimes ) ;
573
597
walk ( this) ;
@@ -597,19 +621,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
597
621
break ;
598
622
}
599
623
600
- EarlyScope ( lifetimes, s) => {
624
+ EarlyScope ( lifetimes, start , s) => {
601
625
match search_lifetimes ( lifetimes, lifetime_ref) {
602
- Some ( ( mut index, lifetime_def) ) => {
603
- // Adjust for nested early scopes, e.g. in methods.
604
- let mut parent = s;
605
- while let EarlyScope ( lifetimes, s) = * parent {
606
- index += lifetimes. len ( ) as u32 ;
607
- parent = s;
608
- }
609
- assert_eq ! ( * parent, RootScope ) ;
610
-
626
+ Some ( ( index, lifetime_def) ) => {
611
627
let decl_id = lifetime_def. id ;
612
- let def = DefEarlyBoundRegion ( index, decl_id) ;
628
+ let def = DefEarlyBoundRegion ( start + index, decl_id) ;
613
629
self . insert_lifetime ( lifetime_ref, def) ;
614
630
return ;
615
631
}
@@ -671,7 +687,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
671
687
break ;
672
688
}
673
689
674
- EarlyScope ( lifetimes, s) |
690
+ EarlyScope ( lifetimes, _ , s) |
675
691
LateScope ( lifetimes, s) => {
676
692
search_result = search_lifetimes ( lifetimes, lifetime_ref) ;
677
693
if search_result. is_some ( ) {
@@ -767,7 +783,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
767
783
return ;
768
784
}
769
785
770
- EarlyScope ( lifetimes, s) |
786
+ EarlyScope ( lifetimes, _ , s) |
771
787
LateScope ( lifetimes, s) => {
772
788
if let Some ( ( _, lifetime_def) ) = search_lifetimes ( lifetimes, lifetime) {
773
789
signal_shadowing_problem (
0 commit comments