@@ -274,10 +274,8 @@ enum Scope<'a> {
274
274
275
275
#[ derive( Copy , Clone , Debug ) ]
276
276
enum BinderScopeType {
277
- /// In a syntactic trait ref, this represents the outermost binder. So, if
278
- /// you had `T: for<'a> Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'a>`
279
- /// scope uses `PolyTraitRef`.
280
- PolyTraitRef ,
277
+ /// Any non-concatenating binder scopes.
278
+ Normal ,
281
279
/// Within a syntactic trait ref, there may be multiple poly trait refs that
282
280
/// are nested (under the `associcated_type_bounds` feature). The binders of
283
281
/// the innner poly trait refs are extended from the outer poly trait refs
@@ -288,10 +286,6 @@ enum BinderScopeType {
288
286
/// out any lifetimes because they aren't needed to show the two scopes).
289
287
/// The inner `for<>` has a scope of `Concatenating`.
290
288
Concatenating ,
291
- /// Any other binder scopes. These are "normal" in that they increase the binder
292
- /// depth, are fully syntactic, don't concatenate, and don't have special syntactical
293
- /// considerations.
294
- Other ,
295
289
}
296
290
297
291
// A helper struct for debugging scopes without printing parent scopes
@@ -573,6 +567,43 @@ fn late_region_as_bound_region<'tcx>(tcx: TyCtxt<'tcx>, region: &Region) -> ty::
573
567
}
574
568
}
575
569
570
+ impl < ' a , ' tcx > LifetimeContext < ' a , ' tcx > {
571
+ /// Returns the binders in scope and the type of `Binder` that should be created for a poly trait ref.
572
+ fn poly_trait_ref_binder_info ( & mut self ) -> ( Vec < ty:: BoundVariableKind > , BinderScopeType ) {
573
+ let mut scope = self . scope ;
574
+ let mut supertrait_lifetimes = vec ! [ ] ;
575
+ loop {
576
+ match scope {
577
+ Scope :: Body { .. } | Scope :: Root => {
578
+ break ( vec ! [ ] , BinderScopeType :: Normal ) ;
579
+ }
580
+
581
+ Scope :: Elision { s, .. } | Scope :: ObjectLifetimeDefault { s, .. } => {
582
+ scope = s;
583
+ }
584
+
585
+ Scope :: Supertrait { s, lifetimes } => {
586
+ supertrait_lifetimes = lifetimes. clone ( ) ;
587
+ scope = s;
588
+ }
589
+
590
+ Scope :: TraitRefBoundary { .. } => {
591
+ // We should only see super trait lifetimes if there is a `Binder` above
592
+ assert ! ( supertrait_lifetimes. is_empty( ) ) ;
593
+ break ( vec ! [ ] , BinderScopeType :: Normal ) ;
594
+ }
595
+
596
+ Scope :: Binder { hir_id, .. } => {
597
+ // Nested poly trait refs have the binders concatenated
598
+ let mut full_binders =
599
+ self . map . late_bound_vars . entry ( * hir_id) . or_default ( ) . clone ( ) ;
600
+ full_binders. extend ( supertrait_lifetimes. into_iter ( ) ) ;
601
+ break ( full_binders, BinderScopeType :: Concatenating ) ;
602
+ }
603
+ }
604
+ }
605
+ }
606
+ }
576
607
impl < ' a , ' tcx > Visitor < ' tcx > for LifetimeContext < ' a , ' tcx > {
577
608
type Map = Map < ' tcx > ;
578
609
@@ -630,7 +661,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
630
661
s : self . scope ,
631
662
track_lifetime_uses : true ,
632
663
opaque_type_parent : false ,
633
- scope_type : BinderScopeType :: Other ,
664
+ scope_type : BinderScopeType :: Normal ,
634
665
} ;
635
666
self . with ( scope, move |_old_scope, this| {
636
667
intravisit:: walk_fn ( this, fk, fd, b, s, hir_id)
@@ -755,7 +786,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
755
786
next_early_index : index + non_lifetime_count,
756
787
opaque_type_parent : true ,
757
788
track_lifetime_uses,
758
- scope_type : BinderScopeType :: Other ,
789
+ scope_type : BinderScopeType :: Normal ,
759
790
s : ROOT_SCOPE ,
760
791
} ;
761
792
self . with ( scope, |old_scope, this| {
@@ -827,7 +858,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
827
858
next_early_index,
828
859
track_lifetime_uses : true ,
829
860
opaque_type_parent : false ,
830
- scope_type : BinderScopeType :: Other ,
861
+ scope_type : BinderScopeType :: Normal ,
831
862
} ;
832
863
self . with ( scope, |old_scope, this| {
833
864
// a bare fn has no bounds, so everything
@@ -1023,7 +1054,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
1023
1054
s : this. scope ,
1024
1055
track_lifetime_uses : true ,
1025
1056
opaque_type_parent : false ,
1026
- scope_type : BinderScopeType :: Other ,
1057
+ scope_type : BinderScopeType :: Normal ,
1027
1058
} ;
1028
1059
this. with ( scope, |_old_scope, this| {
1029
1060
this. visit_generics ( generics) ;
@@ -1043,7 +1074,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
1043
1074
s : self . scope ,
1044
1075
track_lifetime_uses : true ,
1045
1076
opaque_type_parent : false ,
1046
- scope_type : BinderScopeType :: Other ,
1077
+ scope_type : BinderScopeType :: Normal ,
1047
1078
} ;
1048
1079
self . with ( scope, |_old_scope, this| {
1049
1080
let scope = Scope :: TraitRefBoundary { s : this. scope } ;
@@ -1102,7 +1133,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
1102
1133
s : self . scope ,
1103
1134
track_lifetime_uses : true ,
1104
1135
opaque_type_parent : true ,
1105
- scope_type : BinderScopeType :: Other ,
1136
+ scope_type : BinderScopeType :: Normal ,
1106
1137
} ;
1107
1138
self . with ( scope, |old_scope, this| {
1108
1139
this. check_lifetime_params ( old_scope, & generics. params ) ;
@@ -1171,7 +1202,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
1171
1202
s : self . scope ,
1172
1203
track_lifetime_uses : true ,
1173
1204
opaque_type_parent : true ,
1174
- scope_type : BinderScopeType :: Other ,
1205
+ scope_type : BinderScopeType :: Normal ,
1175
1206
} ;
1176
1207
self . with ( scope, |old_scope, this| {
1177
1208
this. check_lifetime_params ( old_scope, & generics. params ) ;
@@ -1287,7 +1318,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
1287
1318
next_early_index,
1288
1319
track_lifetime_uses : true ,
1289
1320
opaque_type_parent : false ,
1290
- scope_type : BinderScopeType :: PolyTraitRef ,
1321
+ scope_type : BinderScopeType :: Normal ,
1291
1322
} ;
1292
1323
this. with ( scope, |old_scope, this| {
1293
1324
this. check_lifetime_params ( old_scope, & bound_generic_params) ;
@@ -1317,32 +1348,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
1317
1348
}
1318
1349
1319
1350
fn visit_param_bound ( & mut self , bound : & ' tcx hir:: GenericBound < ' tcx > ) {
1320
- // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
1321
- // through the regular poly trait ref code, so we don't get another
1322
- // chance to introduce a binder. For now, I'm keeping the existing logic
1323
- // of "if there isn't a Binder scope above us, add one", but I
1324
- // imagine there's a better way to go about this.
1325
- let mut scope = self . scope ;
1326
- let ( binders, scope_type) = loop {
1327
- match scope {
1328
- Scope :: TraitRefBoundary { .. } | Scope :: Body { .. } | Scope :: Root => {
1329
- break ( vec ! [ ] , BinderScopeType :: PolyTraitRef ) ;
1330
- }
1331
-
1332
- Scope :: Binder { hir_id, .. } => {
1333
- let binders = self . map . late_bound_vars . entry ( * hir_id) . or_default ( ) . clone ( ) ;
1334
- break ( binders, BinderScopeType :: Concatenating ) ;
1335
- }
1336
-
1337
- Scope :: Elision { s, .. }
1338
- | Scope :: ObjectLifetimeDefault { s, .. }
1339
- | Scope :: Supertrait { s, .. } => {
1340
- scope = s;
1341
- }
1342
- }
1343
- } ;
1344
1351
match bound {
1345
1352
hir:: GenericBound :: LangItemTrait ( _, _, hir_id, _) => {
1353
+ // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
1354
+ // through the regular poly trait ref code, so we don't get another
1355
+ // chance to introduce a binder. For now, I'm keeping the existing logic
1356
+ // of "if there isn't a Binder scope above us, add one", but I
1357
+ // imagine there's a better way to go about this.
1358
+ let ( binders, scope_type) = self . poly_trait_ref_binder_info ( ) ;
1359
+
1346
1360
self . map . late_bound_vars . insert ( * hir_id, binders) ;
1347
1361
let scope = Scope :: Binder {
1348
1362
hir_id : * hir_id,
@@ -1371,44 +1385,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
1371
1385
let should_pop_missing_lt = self . is_trait_ref_fn_scope ( trait_ref) ;
1372
1386
1373
1387
let next_early_index = self . next_early_index ( ) ;
1374
- let mut scope = self . scope ;
1375
- let mut supertrait_lifetimes = vec ! [ ] ;
1376
- let ( mut binders, scope_type) = loop {
1377
- match scope {
1378
- Scope :: Body { .. } | Scope :: Root => {
1379
- break ( vec ! [ ] , BinderScopeType :: PolyTraitRef ) ;
1380
- }
1381
-
1382
- Scope :: Elision { s, .. } | Scope :: ObjectLifetimeDefault { s, .. } => {
1383
- scope = s;
1384
- }
1385
-
1386
- Scope :: Supertrait { s, lifetimes } => {
1387
- supertrait_lifetimes = lifetimes. clone ( ) ;
1388
- scope = s;
1389
- }
1390
-
1391
- Scope :: TraitRefBoundary { .. } => {
1392
- // We should only see super trait lifetimes if there is a `Binder` above
1393
- assert ! ( supertrait_lifetimes. is_empty( ) ) ;
1394
- break ( vec ! [ ] , BinderScopeType :: PolyTraitRef ) ;
1395
- }
1396
-
1397
- Scope :: Binder { hir_id, scope_type, .. } => {
1398
- if let BinderScopeType :: Other = scope_type {
1399
- bug ! (
1400
- "Expected all syntacic poly trait refs to be surrounded by a `TraitRefBoundary`"
1401
- )
1402
- }
1403
-
1404
- // Nested poly trait refs have the binders concatenated
1405
- let mut full_binders =
1406
- self . map . late_bound_vars . entry ( * hir_id) . or_default ( ) . clone ( ) ;
1407
- full_binders. extend ( supertrait_lifetimes. into_iter ( ) ) ;
1408
- break ( full_binders, BinderScopeType :: Concatenating ) ;
1409
- }
1410
- }
1411
- } ;
1388
+ let ( mut binders, scope_type) = self . poly_trait_ref_binder_info ( ) ;
1412
1389
1413
1390
let initial_bound_vars = binders. len ( ) as u32 ;
1414
1391
let mut lifetimes: FxHashMap < hir:: ParamName , Region > = FxHashMap :: default ( ) ;
@@ -2185,7 +2162,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2185
2162
s : self . scope ,
2186
2163
opaque_type_parent : true ,
2187
2164
track_lifetime_uses : false ,
2188
- scope_type : BinderScopeType :: Other ,
2165
+ scope_type : BinderScopeType :: Normal ,
2189
2166
} ;
2190
2167
self . with ( scope, move |old_scope, this| {
2191
2168
this. check_lifetime_params ( old_scope, & generics. params ) ;
@@ -2270,8 +2247,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
2270
2247
_ => bug ! ( "expected LifetimeName::Param" ) ,
2271
2248
}
2272
2249
match scope_type {
2273
- BinderScopeType :: Other => late_depth += 1 ,
2274
- BinderScopeType :: PolyTraitRef => late_depth += 1 ,
2250
+ BinderScopeType :: Normal => late_depth += 1 ,
2275
2251
BinderScopeType :: Concatenating => { }
2276
2252
}
2277
2253
scope = s;
@@ -3001,8 +2977,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
3001
2977
}
3002
2978
}
3003
2979
match scope_type {
3004
- BinderScopeType :: Other => late_depth += 1 ,
3005
- BinderScopeType :: PolyTraitRef => late_depth += 1 ,
2980
+ BinderScopeType :: Normal => late_depth += 1 ,
3006
2981
BinderScopeType :: Concatenating => { }
3007
2982
}
3008
2983
scope = s;
@@ -3165,8 +3140,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
3165
3140
match * scope {
3166
3141
Scope :: Binder { s, scope_type, .. } => {
3167
3142
match scope_type {
3168
- BinderScopeType :: Other => late_depth += 1 ,
3169
- BinderScopeType :: PolyTraitRef => late_depth += 1 ,
3143
+ BinderScopeType :: Normal => late_depth += 1 ,
3170
3144
BinderScopeType :: Concatenating => { }
3171
3145
}
3172
3146
scope = s;
0 commit comments