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