@@ -70,9 +70,10 @@ impl<'tcx> Region<'tcx> {
70
70
pub fn new_late_param (
71
71
tcx : TyCtxt < ' tcx > ,
72
72
scope : DefId ,
73
- bound_region : ty :: BoundRegionKind ,
73
+ kind : LateParamRegionKind ,
74
74
) -> Region < ' tcx > {
75
- tcx. intern_region ( ty:: ReLateParam ( ty:: LateParamRegion { scope, bound_region } ) )
75
+ let data = LateParamRegion { scope, kind } ;
76
+ tcx. intern_region ( ty:: ReLateParam ( data) )
76
77
}
77
78
78
79
#[ inline]
@@ -125,8 +126,8 @@ impl<'tcx> Region<'tcx> {
125
126
match kind {
126
127
ty:: ReEarlyParam ( region) => Region :: new_early_param ( tcx, region) ,
127
128
ty:: ReBound ( debruijn, region) => Region :: new_bound ( tcx, debruijn, region) ,
128
- ty:: ReLateParam ( ty:: LateParamRegion { scope, bound_region } ) => {
129
- Region :: new_late_param ( tcx, scope, bound_region )
129
+ ty:: ReLateParam ( ty:: LateParamRegion { scope, kind } ) => {
130
+ Region :: new_late_param ( tcx, scope, kind )
130
131
}
131
132
ty:: ReStatic => tcx. lifetimes . re_static ,
132
133
ty:: ReVar ( vid) => Region :: new_var ( tcx, vid) ,
@@ -166,7 +167,7 @@ impl<'tcx> Region<'tcx> {
166
167
match * self {
167
168
ty:: ReEarlyParam ( ebr) => Some ( ebr. name ) ,
168
169
ty:: ReBound ( _, br) => br. kind . get_name ( ) ,
169
- ty:: ReLateParam ( fr) => fr. bound_region . get_name ( ) ,
170
+ ty:: ReLateParam ( fr) => fr. kind . get_name ( ) ,
170
171
ty:: ReStatic => Some ( kw:: StaticLifetime ) ,
171
172
ty:: RePlaceholder ( placeholder) => placeholder. bound . kind . get_name ( ) ,
172
173
_ => None ,
@@ -188,7 +189,7 @@ impl<'tcx> Region<'tcx> {
188
189
match * self {
189
190
ty:: ReEarlyParam ( ebr) => ebr. has_name ( ) ,
190
191
ty:: ReBound ( _, br) => br. kind . is_named ( ) ,
191
- ty:: ReLateParam ( fr) => fr. bound_region . is_named ( ) ,
192
+ ty:: ReLateParam ( fr) => fr. kind . is_named ( ) ,
192
193
ty:: ReStatic => true ,
193
194
ty:: ReVar ( ..) => false ,
194
195
ty:: RePlaceholder ( placeholder) => placeholder. bound . kind . is_named ( ) ,
@@ -311,7 +312,7 @@ impl<'tcx> Region<'tcx> {
311
312
Some ( tcx. generics_of ( binding_item) . region_param ( ebr, tcx) . def_id )
312
313
}
313
314
ty:: ReLateParam ( ty:: LateParamRegion {
314
- bound_region : ty:: BoundRegionKind :: Named ( def_id, _) ,
315
+ kind : ty:: LateParamRegionKind :: Named ( def_id, _) ,
315
316
..
316
317
} ) => Some ( def_id) ,
317
318
_ => None ,
@@ -359,7 +360,71 @@ impl std::fmt::Debug for EarlyParamRegion {
359
360
/// different parameters apart.
360
361
pub struct LateParamRegion {
361
362
pub scope : DefId ,
362
- pub bound_region : BoundRegionKind ,
363
+ pub kind : LateParamRegionKind ,
364
+ }
365
+
366
+ /// When liberating bound regions, we map their [`BoundRegionKind`]
367
+ /// to this as we need to track the index of anonymous regions. We
368
+ /// otherwise end up liberating multiple bound regions to the same
369
+ /// late-bound region.
370
+ #[ derive( Clone , PartialEq , Eq , Hash , TyEncodable , TyDecodable , Copy ) ]
371
+ #[ derive( HashStable ) ]
372
+ pub enum LateParamRegionKind {
373
+ /// An anonymous region parameter for a given fn (&T)
374
+ ///
375
+ /// Unlike [`BoundRegionKind::Anon`], this tracks the index of the
376
+ /// liberated bound region.
377
+ ///
378
+ /// We should ideally never liberate anonymous regions, but do so for the
379
+ /// sake of diagnostics in `FnCtxt::sig_of_closure_with_expectation`.
380
+ Anon ( u32 ) ,
381
+
382
+ /// Named region parameters for functions (a in &'a T)
383
+ ///
384
+ /// The `DefId` is needed to distinguish free regions in
385
+ /// the event of shadowing.
386
+ Named ( DefId , Symbol ) ,
387
+
388
+ /// Anonymous region for the implicit env pointer parameter
389
+ /// to a closure
390
+ ClosureEnv ,
391
+ }
392
+
393
+ impl LateParamRegionKind {
394
+ pub fn from_bound ( var : BoundVar , br : BoundRegionKind ) -> LateParamRegionKind {
395
+ match br {
396
+ BoundRegionKind :: Anon => LateParamRegionKind :: Anon ( var. as_u32 ( ) ) ,
397
+ BoundRegionKind :: Named ( def_id, name) => LateParamRegionKind :: Named ( def_id, name) ,
398
+ BoundRegionKind :: ClosureEnv => LateParamRegionKind :: ClosureEnv ,
399
+ }
400
+ }
401
+
402
+ pub fn is_named ( & self ) -> bool {
403
+ match * self {
404
+ LateParamRegionKind :: Named ( _, name) => {
405
+ name != kw:: UnderscoreLifetime && name != kw:: Empty
406
+ }
407
+ _ => false ,
408
+ }
409
+ }
410
+
411
+ pub fn get_name ( & self ) -> Option < Symbol > {
412
+ if self . is_named ( ) {
413
+ match * self {
414
+ LateParamRegionKind :: Named ( _, name) => return Some ( name) ,
415
+ _ => unreachable ! ( ) ,
416
+ }
417
+ }
418
+
419
+ None
420
+ }
421
+
422
+ pub fn get_id ( & self ) -> Option < DefId > {
423
+ match * self {
424
+ LateParamRegionKind :: Named ( id, _) => Some ( id) ,
425
+ _ => None ,
426
+ }
427
+ }
363
428
}
364
429
365
430
#[ derive( Clone , PartialEq , Eq , Hash , TyEncodable , TyDecodable , Copy ) ]
0 commit comments