@@ -304,8 +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 ( |constraint| {
308
- debug ! ( "expansion: constraint={:?}" , constraint) ;
307
+ let mut process_constraint = |constraint : & Constraint < ' tcx > | {
309
308
let ( a_region, b_vid, b_data, retain) = match * constraint {
310
309
Constraint :: RegSubVar ( a_region, b_vid) => {
311
310
let b_data = var_values. value_mut ( b_vid) ;
@@ -331,7 +330,33 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
331
330
332
331
let changed = self . expand_node ( a_region, b_vid, b_data) ;
333
332
( changed, retain)
334
- } )
333
+ } ;
334
+
335
+ // Using bitsets to track the remaining elements is faster than using a
336
+ // `Vec` by itself (which requires removing elements, which requires
337
+ // element shuffling, which is slow).
338
+ let constraints: Vec < _ > = self . data . constraints . keys ( ) . collect ( ) ;
339
+ let mut live_indices: BitSet < usize > = BitSet :: new_filled ( constraints. len ( ) ) ;
340
+ let mut killed_indices: BitSet < usize > = BitSet :: new_empty ( constraints. len ( ) ) ;
341
+ let mut changed = true ;
342
+ while changed {
343
+ changed = false ;
344
+ for index in live_indices. iter ( ) {
345
+ let constraint = constraints[ index] ;
346
+ let ( edge_changed, retain) = process_constraint ( constraint) ;
347
+ if edge_changed {
348
+ changed = true ;
349
+ }
350
+ if !retain {
351
+ let changed = killed_indices. insert ( index) ;
352
+ debug_assert ! ( changed) ;
353
+ }
354
+ }
355
+ live_indices. subtract ( & killed_indices) ;
356
+
357
+ // We could clear `killed_indices` here, but we don't need to and
358
+ // it's cheaper not to.
359
+ }
335
360
}
336
361
337
362
// This function is very hot in some workloads. There's a single callsite
@@ -866,42 +891,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
866
891
}
867
892
}
868
893
869
- fn iterate_until_fixed_point < F > ( & self , mut body : F )
870
- where
871
- F : FnMut ( & Constraint < ' tcx > ) -> ( bool , bool ) ,
872
- {
873
- // Using bitsets to track the remaining elements is faster than using a
874
- // `Vec` by itself (which requires removing elements, which requires
875
- // element shuffling, which is slow).
876
- let constraints: Vec < _ > = self . data . constraints . keys ( ) . collect ( ) ;
877
- let mut live_indices: BitSet < usize > = BitSet :: new_filled ( constraints. len ( ) ) ;
878
- let mut killed_indices: BitSet < usize > = BitSet :: new_empty ( constraints. len ( ) ) ;
879
- let mut iteration = 0 ;
880
- let mut changed = true ;
881
- while changed {
882
- changed = false ;
883
- iteration += 1 ;
884
- debug ! ( "---- Expansion iteration {}" , iteration) ;
885
- for index in live_indices. iter ( ) {
886
- let constraint = constraints[ index] ;
887
- let ( edge_changed, retain) = body ( constraint) ;
888
- if edge_changed {
889
- debug ! ( "updated due to constraint {:?}" , constraint) ;
890
- changed = true ;
891
- }
892
- if !retain {
893
- let changed = killed_indices. insert ( index) ;
894
- debug_assert ! ( changed) ;
895
- }
896
- }
897
- live_indices. subtract ( & killed_indices) ;
898
-
899
- // We could clear `killed_indices` here, but we don't need to and
900
- // it's cheaper not to.
901
- }
902
- debug ! ( "---- Expansion complete after {} iteration(s)" , iteration) ;
903
- }
904
-
905
894
fn bound_is_met (
906
895
& self ,
907
896
bound : & VerifyBound < ' tcx > ,
0 commit comments