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