@@ -70,9 +70,21 @@ 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) )
77
+ }
78
+
79
+ #[ inline]
80
+ pub fn new_late_param_from_bound (
81
+ tcx : TyCtxt < ' tcx > ,
82
+ scope : DefId ,
83
+ bound : BoundRegion ,
84
+ ) -> Region < ' tcx > {
85
+ let data =
86
+ LateParamRegion { scope, kind : LateParamRegionKind :: from_bound ( bound. var , bound. kind ) } ;
87
+ tcx. intern_region ( ty:: ReLateParam ( data) )
76
88
}
77
89
78
90
#[ inline]
@@ -125,8 +137,8 @@ impl<'tcx> Region<'tcx> {
125
137
match kind {
126
138
ty:: ReEarlyParam ( region) => Region :: new_early_param ( tcx, region) ,
127
139
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 )
140
+ ty:: ReLateParam ( ty:: LateParamRegion { scope, kind } ) => {
141
+ Region :: new_late_param ( tcx, scope, kind )
130
142
}
131
143
ty:: ReStatic => tcx. lifetimes . re_static ,
132
144
ty:: ReVar ( vid) => Region :: new_var ( tcx, vid) ,
@@ -166,7 +178,7 @@ impl<'tcx> Region<'tcx> {
166
178
match * self {
167
179
ty:: ReEarlyParam ( ebr) => Some ( ebr. name ) ,
168
180
ty:: ReBound ( _, br) => br. kind . get_name ( ) ,
169
- ty:: ReLateParam ( fr) => fr. bound_region . get_name ( ) ,
181
+ ty:: ReLateParam ( fr) => fr. kind . get_name ( ) ,
170
182
ty:: ReStatic => Some ( kw:: StaticLifetime ) ,
171
183
ty:: RePlaceholder ( placeholder) => placeholder. bound . kind . get_name ( ) ,
172
184
_ => None ,
@@ -188,7 +200,7 @@ impl<'tcx> Region<'tcx> {
188
200
match * self {
189
201
ty:: ReEarlyParam ( ebr) => ebr. has_name ( ) ,
190
202
ty:: ReBound ( _, br) => br. kind . is_named ( ) ,
191
- ty:: ReLateParam ( fr) => fr. bound_region . is_named ( ) ,
203
+ ty:: ReLateParam ( fr) => fr. kind . is_named ( ) ,
192
204
ty:: ReStatic => true ,
193
205
ty:: ReVar ( ..) => false ,
194
206
ty:: RePlaceholder ( placeholder) => placeholder. bound . kind . is_named ( ) ,
@@ -311,7 +323,7 @@ impl<'tcx> Region<'tcx> {
311
323
Some ( tcx. generics_of ( binding_item) . region_param ( ebr, tcx) . def_id )
312
324
}
313
325
ty:: ReLateParam ( ty:: LateParamRegion {
314
- bound_region : ty:: BoundRegionKind :: Named ( def_id, _) ,
326
+ kind : ty:: LateParamRegionKind :: Named ( def_id, _) ,
315
327
..
316
328
} ) => Some ( def_id) ,
317
329
_ => None ,
@@ -359,7 +371,71 @@ impl std::fmt::Debug for EarlyParamRegion {
359
371
/// different parameters apart.
360
372
pub struct LateParamRegion {
361
373
pub scope : DefId ,
362
- pub bound_region : BoundRegionKind ,
374
+ pub kind : LateParamRegionKind ,
375
+ }
376
+
377
+ /// When liberating bound regions, we map their [`BoundRegionKind`]
378
+ /// to this as we need to track the index of anonymous regions. We
379
+ /// otherwise end up liberating multiple bound regions to the same
380
+ /// late-bound region.
381
+ #[ derive( Clone , PartialEq , Eq , Hash , TyEncodable , TyDecodable , Copy ) ]
382
+ #[ derive( HashStable ) ]
383
+ pub enum LateParamRegionKind {
384
+ /// An anonymous region parameter for a given fn (&T)
385
+ ///
386
+ /// Unlike [`BoundRegionKind::Anon`], this tracks the index of the
387
+ /// liberated bound region.
388
+ ///
389
+ /// We should ideally never liberate anonymous regions, but do so for the
390
+ /// sake of diagnostics in `FnCtxt::sig_of_closure_with_expectation`.
391
+ Anon ( u32 ) ,
392
+
393
+ /// Named region parameters for functions (a in &'a T)
394
+ ///
395
+ /// The `DefId` is needed to distinguish free regions in
396
+ /// the event of shadowing.
397
+ Named ( DefId , Symbol ) ,
398
+
399
+ /// Anonymous region for the implicit env pointer parameter
400
+ /// to a closure
401
+ ClosureEnv ,
402
+ }
403
+
404
+ impl LateParamRegionKind {
405
+ pub fn from_bound ( var : BoundVar , br : BoundRegionKind ) -> LateParamRegionKind {
406
+ match br {
407
+ BoundRegionKind :: Anon => LateParamRegionKind :: Anon ( var. as_u32 ( ) ) ,
408
+ BoundRegionKind :: Named ( def_id, name) => LateParamRegionKind :: Named ( def_id, name) ,
409
+ BoundRegionKind :: ClosureEnv => LateParamRegionKind :: ClosureEnv ,
410
+ }
411
+ }
412
+
413
+ pub fn is_named ( & self ) -> bool {
414
+ match * self {
415
+ LateParamRegionKind :: Named ( _, name) => {
416
+ name != kw:: UnderscoreLifetime && name != kw:: Empty
417
+ }
418
+ _ => false ,
419
+ }
420
+ }
421
+
422
+ pub fn get_name ( & self ) -> Option < Symbol > {
423
+ if self . is_named ( ) {
424
+ match * self {
425
+ LateParamRegionKind :: Named ( _, name) => return Some ( name) ,
426
+ _ => unreachable ! ( ) ,
427
+ }
428
+ }
429
+
430
+ None
431
+ }
432
+
433
+ pub fn get_id ( & self ) -> Option < DefId > {
434
+ match * self {
435
+ LateParamRegionKind :: Named ( id, _) => Some ( id) ,
436
+ _ => None ,
437
+ }
438
+ }
363
439
}
364
440
365
441
#[ derive( Clone , PartialEq , Eq , Hash , TyEncodable , TyDecodable , Copy ) ]
0 commit comments