@@ -172,7 +172,6 @@ enum Scope<'a> {
172
172
/// it should be shifted by the number of `Binder`s in between the
173
173
/// declaration `Binder` and the location it's referenced from.
174
174
Binder {
175
- scope_type : BinderScopeType ,
176
175
s : ScopeRef < ' a > ,
177
176
} ,
178
177
@@ -199,35 +198,19 @@ enum Scope<'a> {
199
198
Root ,
200
199
}
201
200
202
- #[ derive( Copy , Clone , Debug ) ]
203
- enum BinderScopeType {
204
- /// Any non-concatenating binder scopes.
205
- Normal ,
206
- /// Within a syntactic trait ref, there may be multiple poly trait refs that
207
- /// are nested (under the `associated_type_bounds` feature). The binders of
208
- /// the inner poly trait refs are extended from the outer poly trait refs
209
- /// and don't increase the late bound depth. If you had
210
- /// `T: for<'a> Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'b>` scope
211
- /// would be `Concatenating`. This also used in trait refs in where clauses
212
- /// where we have two binders `for<> T: for<> Foo` (I've intentionally left
213
- /// out any lifetimes because they aren't needed to show the two scopes).
214
- /// The inner `for<>` has a scope of `Concatenating`.
215
- Concatenating ,
216
- }
217
-
218
201
type ScopeRef < ' a > = & ' a Scope < ' a > ;
219
202
220
203
const ROOT_SCOPE : ScopeRef < ' static > = & Scope :: Root ;
221
204
222
205
impl < ' a , ' tcx > LifetimeContext < ' a , ' tcx > {
223
206
/// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref.
224
- fn poly_trait_ref_binder_info ( & mut self ) -> BinderScopeType {
207
+ fn poly_trait_ref_needs_binder ( & mut self ) -> bool {
225
208
let mut scope = self . scope ;
226
209
loop {
227
210
match scope {
228
211
// Nested poly trait refs have the binders concatenated
229
- Scope :: Binder { .. } => break BinderScopeType :: Concatenating ,
230
- Scope :: Body | Scope :: Root => break BinderScopeType :: Normal ,
212
+ Scope :: Binder { .. } => break false ,
213
+ Scope :: Body | Scope :: Root => break true ,
231
214
Scope :: Static { s, .. } | Scope :: ObjectLifetimeDefault { s, .. } => scope = s,
232
215
}
233
216
}
@@ -249,7 +232,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
249
232
250
233
fn visit_expr ( & mut self , e : & ' tcx hir:: Expr < ' tcx > ) {
251
234
if let hir:: ExprKind :: Closure ( ..) = e. kind {
252
- let scope = Scope :: Binder { s : self . scope , scope_type : BinderScopeType :: Normal } ;
235
+ let scope = Scope :: Binder { s : self . scope } ;
253
236
self . with ( scope, |this| {
254
237
// a closure has no bounds, so everything
255
238
// contained within is scoped within its binder.
@@ -287,7 +270,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
287
270
| hir:: ItemKind :: Fn ( ..)
288
271
| hir:: ItemKind :: Impl ( ..) => {
289
272
// These kinds of items have only early-bound lifetime parameters.
290
- let scope = Scope :: Binder { scope_type : BinderScopeType :: Normal , s : ROOT_SCOPE } ;
273
+ let scope = Scope :: Binder { s : ROOT_SCOPE } ;
291
274
self . with ( scope, |this| intravisit:: walk_item ( this, item) ) ;
292
275
}
293
276
}
@@ -296,7 +279,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
296
279
fn visit_foreign_item ( & mut self , item : & ' tcx hir:: ForeignItem < ' tcx > ) {
297
280
match item. kind {
298
281
hir:: ForeignItemKind :: Fn ( ..) => {
299
- let scope = Scope :: Binder { s : self . scope , scope_type : BinderScopeType :: Normal } ;
282
+ let scope = Scope :: Binder { s : self . scope } ;
300
283
self . with ( scope, |this| intravisit:: walk_foreign_item ( this, item) )
301
284
}
302
285
hir:: ForeignItemKind :: Static ( ..) | hir:: ForeignItemKind :: Type => {
@@ -309,7 +292,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
309
292
fn visit_ty ( & mut self , ty : & ' tcx hir:: Ty < ' tcx > ) {
310
293
match ty. kind {
311
294
hir:: TyKind :: BareFn ( ..) => {
312
- let scope = Scope :: Binder { s : self . scope , scope_type : BinderScopeType :: Normal } ;
295
+ let scope = Scope :: Binder { s : self . scope } ;
313
296
self . with ( scope, |this| {
314
297
// a bare fn has no bounds, so everything
315
298
// contained within is scoped within its binder.
@@ -342,7 +325,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
342
325
use self :: hir:: TraitItemKind :: * ;
343
326
match trait_item. kind {
344
327
Fn ( ..) | Type ( ..) => {
345
- let scope = Scope :: Binder { s : self . scope , scope_type : BinderScopeType :: Normal } ;
328
+ let scope = Scope :: Binder { s : self . scope } ;
346
329
self . with ( scope, |this| intravisit:: walk_trait_item ( this, trait_item) ) ;
347
330
}
348
331
// Only methods and types support generics.
@@ -354,7 +337,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
354
337
use self :: hir:: ImplItemKind :: * ;
355
338
match impl_item. kind {
356
339
Fn ( ..) | TyAlias ( ..) => {
357
- let scope = Scope :: Binder { s : self . scope , scope_type : BinderScopeType :: Normal } ;
340
+ let scope = Scope :: Binder { s : self . scope } ;
358
341
self . with ( scope, |this| intravisit:: walk_impl_item ( this, impl_item) ) ;
359
342
}
360
343
// Only methods and types support generics.
@@ -378,7 +361,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
378
361
// scope. If there happens to be a nested poly trait ref (an error), that
379
362
// will be `Concatenating` anyways, so we don't have to worry about the depth
380
363
// being wrong.
381
- let scope = Scope :: Binder { s : self . scope , scope_type : BinderScopeType :: Normal } ;
364
+ let scope = Scope :: Binder { s : self . scope } ;
382
365
self . with ( scope, |this| intravisit:: walk_where_predicate ( this, predicate) )
383
366
}
384
367
& hir:: WherePredicate :: RegionPredicate ( ..) | & hir:: WherePredicate :: EqPredicate ( ..) => {
@@ -389,15 +372,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
389
372
390
373
fn visit_param_bound ( & mut self , bound : & ' tcx hir:: GenericBound < ' tcx > ) {
391
374
match bound {
392
- hir:: GenericBound :: LangItemTrait ( ..) => {
393
- // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
394
- // through the regular poly trait ref code, so we don't get another
395
- // chance to introduce a binder. For now, I'm keeping the existing logic
396
- // of "if there isn't a Binder scope above us, add one", but I
397
- // imagine there's a better way to go about this.
398
- let scope_type = self . poly_trait_ref_binder_info ( ) ;
399
-
400
- let scope = Scope :: Binder { s : self . scope , scope_type } ;
375
+ // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
376
+ // through the regular poly trait ref code, so we don't get another
377
+ // chance to introduce a binder. For now, I'm keeping the existing logic
378
+ // of "if there isn't a Binder scope above us, add one", but I
379
+ // imagine there's a better way to go about this.
380
+ hir:: GenericBound :: LangItemTrait ( ..) if self . poly_trait_ref_needs_binder ( ) => {
381
+ let scope = Scope :: Binder { s : self . scope } ;
401
382
self . with ( scope, |this| intravisit:: walk_param_bound ( this, bound) ) ;
402
383
}
403
384
_ => intravisit:: walk_param_bound ( self , bound) ,
@@ -411,14 +392,16 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
411
392
) {
412
393
debug ! ( "visit_poly_trait_ref(trait_ref={:?})" , trait_ref) ;
413
394
414
- let scope_type = self . poly_trait_ref_binder_info ( ) ;
415
-
416
- // Always introduce a scope here, even if this is in a where clause and
417
- // we introduced the binders around the bounded Ty. In that case, we
418
- // just reuse the concatenation functionality also present in nested trait
419
- // refs.
420
- let scope = Scope :: Binder { s : self . scope , scope_type } ;
421
- self . with ( scope, |this| intravisit:: walk_poly_trait_ref ( this, trait_ref, modifier) ) ;
395
+ if self . poly_trait_ref_needs_binder ( ) {
396
+ // Always introduce a scope here, even if this is in a where clause and
397
+ // we introduced the binders around the bounded Ty. In that case, we
398
+ // just reuse the concatenation functionality also present in nested trait
399
+ // refs.
400
+ let scope = Scope :: Binder { s : self . scope } ;
401
+ self . with ( scope, |this| intravisit:: walk_poly_trait_ref ( this, trait_ref, modifier) ) ;
402
+ } else {
403
+ intravisit:: walk_poly_trait_ref ( self , trait_ref, modifier) ;
404
+ }
422
405
}
423
406
}
424
407
@@ -601,11 +584,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
601
584
let mut scope = self . scope ;
602
585
let lifetime = loop {
603
586
match * scope {
604
- Scope :: Binder { s, scope_type, .. } => {
605
- match scope_type {
606
- BinderScopeType :: Normal => late_depth += 1 ,
607
- BinderScopeType :: Concatenating => { }
608
- }
587
+ Scope :: Binder { s, .. } => {
588
+ late_depth += 1 ;
609
589
scope = s;
610
590
}
611
591
0 commit comments