@@ -304,7 +304,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
304
304
}
305
305
306
306
fn expansion ( & self , var_values : & mut LexicalRegionResolutions < ' tcx > ) {
307
- self . iterate_until_fixed_point ( "Expansion" , |constraint| {
307
+ self . iterate_until_fixed_point ( |constraint| {
308
308
debug ! ( "expansion: constraint={:?}" , constraint) ;
309
309
let ( a_region, b_vid, b_data, retain) = match * constraint {
310
310
Constraint :: RegSubVar ( a_region, b_vid) => {
@@ -360,13 +360,21 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
360
360
match * b_data {
361
361
VarValue :: Value ( cur_region) => {
362
362
// Identical scopes can show up quite often, if the fixed point
363
- // iteration converges slowly, skip them
363
+ // iteration converges slowly. Skip them. This is purely an
364
+ // optimization.
364
365
if let ( ReScope ( a_scope) , ReScope ( cur_scope) ) = ( a_region, cur_region) {
365
366
if a_scope == cur_scope {
366
367
return false ;
367
368
}
368
369
}
369
370
371
+ // This is a specialized version of the `lub_concrete_regions`
372
+ // check below for a common case, here purely as an
373
+ // optimization.
374
+ if let ReEmpty = a_region {
375
+ return false ;
376
+ }
377
+
370
378
let mut lub = self . lub_concrete_regions ( a_region, cur_region) ;
371
379
if lub == cur_region {
372
380
return false ;
@@ -407,8 +415,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
407
415
408
416
/// Returns the smallest region `c` such that `a <= c` and `b <= c`.
409
417
fn lub_concrete_regions ( & self , a : Region < ' tcx > , b : Region < ' tcx > ) -> Region < ' tcx > {
410
- let tcx = self . tcx ( ) ;
411
-
412
418
match ( a, b) {
413
419
( & ty:: ReClosureBound ( ..) , _)
414
420
| ( _, & ty:: ReClosureBound ( ..) )
@@ -468,15 +474,15 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
468
474
469
475
// otherwise, we don't know what the free region is,
470
476
// so we must conservatively say the LUB is static:
471
- tcx. lifetimes . re_static
477
+ self . tcx ( ) . lifetimes . re_static
472
478
}
473
479
474
480
( & ReScope ( a_id) , & ReScope ( b_id) ) => {
475
481
// The region corresponding to an outer block is a
476
482
// subtype of the region corresponding to an inner
477
483
// block.
478
484
let lub = self . region_rels . region_scope_tree . nearest_common_ancestor ( a_id, b_id) ;
479
- tcx. mk_region ( ReScope ( lub) )
485
+ self . tcx ( ) . mk_region ( ReScope ( lub) )
480
486
}
481
487
482
488
( & ReEarlyBound ( _) , & ReEarlyBound ( _) )
@@ -490,7 +496,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
490
496
if a == b {
491
497
a
492
498
} else {
493
- tcx. lifetimes . re_static
499
+ self . tcx ( ) . lifetimes . re_static
494
500
}
495
501
}
496
502
}
@@ -860,7 +866,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
860
866
}
861
867
}
862
868
863
- fn iterate_until_fixed_point < F > ( & self , tag : & str , mut body : F )
869
+ fn iterate_until_fixed_point < F > ( & self , mut body : F )
864
870
where
865
871
F : FnMut ( & Constraint < ' tcx > ) -> ( bool , bool ) ,
866
872
{
@@ -870,7 +876,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
870
876
while changed {
871
877
changed = false ;
872
878
iteration += 1 ;
873
- debug ! ( "---- {} Iteration {}{}" , "#" , tag , iteration) ;
879
+ debug ! ( "---- Expansion iteration {}" , iteration) ;
874
880
constraints. retain ( |constraint| {
875
881
let ( edge_changed, retain) = body ( constraint) ;
876
882
if edge_changed {
@@ -880,7 +886,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
880
886
retain
881
887
} ) ;
882
888
}
883
- debug ! ( "---- {} Complete after {} iteration(s)" , tag , iteration) ;
889
+ debug ! ( "---- Expansion complete after {} iteration(s)" , iteration) ;
884
890
}
885
891
886
892
fn bound_is_met (
0 commit comments