@@ -19,7 +19,6 @@ use rustc_data_structures::graph::implementation::{
19
19
Direction , Graph , NodeIndex , INCOMING , OUTGOING ,
20
20
} ;
21
21
use rustc_hir:: def_id:: DefId ;
22
- use rustc_index:: bit_set:: BitSet ;
23
22
use rustc_index:: vec:: { Idx , IndexVec } ;
24
23
use rustc_span:: Span ;
25
24
use std:: fmt;
@@ -295,23 +294,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
295
294
}
296
295
297
296
fn expansion ( & self , var_values : & mut LexicalRegionResolutions < ' tcx > ) {
298
- let mut changed = false ;
299
- let mut constraints = Vec :: new ( ) ;
297
+ let mut constraints = IndexVec :: from_elem_n ( Vec :: new ( ) , var_values . values . len ( ) ) ;
298
+ let mut changes = Vec :: new ( ) ;
300
299
for constraint in self . data . constraints . keys ( ) {
301
- let ( a_region, b_vid, b_data) = match * constraint {
300
+ let ( a_vid , a_region, b_vid, b_data) = match * constraint {
302
301
Constraint :: RegSubVar ( a_region, b_vid) => {
303
302
let b_data = var_values. value_mut ( b_vid) ;
304
- ( a_region, b_vid, b_data)
303
+ ( None , a_region, b_vid, b_data)
305
304
}
306
305
Constraint :: VarSubVar ( a_vid, b_vid) => match * var_values. value ( a_vid) {
307
306
VarValue :: ErrorValue => continue ,
308
307
VarValue :: Value ( a_region) => {
309
308
let b_data = var_values. value_mut ( b_vid) ;
310
- match * b_data {
311
- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => ( ) ,
312
- _ => constraints. push ( ( a_vid, b_vid) ) ,
313
- }
314
- ( a_region, b_vid, b_data)
309
+ ( Some ( a_vid) , a_region, b_vid, b_data)
315
310
}
316
311
} ,
317
312
Constraint :: RegSubReg ( ..) | Constraint :: VarSubReg ( ..) => {
@@ -320,54 +315,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
320
315
continue ;
321
316
}
322
317
} ;
323
- let edge_changed = self . expand_node ( a_region, b_vid, b_data) ;
324
- if edge_changed {
325
- changed = true
318
+ if self . expand_node ( a_region, b_vid, b_data) {
319
+ changes. push ( b_vid) ;
320
+ }
321
+ if let Some ( a_vid) = a_vid {
322
+ match * b_data {
323
+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => ( ) ,
324
+ _ => {
325
+ constraints[ a_vid] . push ( ( a_vid, b_vid) ) ;
326
+ constraints[ b_vid] . push ( ( a_vid, b_vid) ) ;
327
+ }
328
+ }
326
329
}
327
330
}
328
331
329
- let mut process_constraint = |a_vid, b_vid| {
330
- let ( a_region, b_data, retain) = match * var_values. value ( a_vid) {
331
- VarValue :: ErrorValue => return ( false , false ) ,
332
- VarValue :: Value ( a_region) => {
333
- let b_data = var_values. value_mut ( b_vid) ;
334
- let retain = match * b_data {
335
- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
336
- _ => true ,
337
- } ;
338
- ( a_region, b_data, retain)
332
+ while let Some ( vid) = changes. pop ( ) {
333
+ constraints[ vid] . retain ( |& ( a_vid, b_vid) | {
334
+ let a_region = match * var_values. value ( a_vid) {
335
+ VarValue :: ErrorValue => return false ,
336
+ VarValue :: Value ( a_region) => a_region,
337
+ } ;
338
+ let b_data = var_values. value_mut ( b_vid) ;
339
+ if self . expand_node ( a_region, b_vid, b_data) {
340
+ changes. push ( b_vid) ;
339
341
}
340
- } ;
341
- let changed = self . expand_node ( a_region, b_vid, b_data) ;
342
- ( changed, retain)
343
- } ;
344
-
345
- // Using bitsets to track the remaining elements is faster than using a
346
- // `Vec` by itself (which requires removing elements, which requires
347
- // element shuffling, which is slow).
348
- let mut live_indices: BitSet < usize > = BitSet :: new_filled ( constraints. len ( ) ) ;
349
- let mut killed_indices: BitSet < usize > = BitSet :: new_empty ( constraints. len ( ) ) ;
350
- while changed {
351
- changed = false ;
352
- for index in live_indices. iter ( ) {
353
- let ( a_vid, b_vid) = constraints[ index] ;
354
- let ( edge_changed, retain) = process_constraint ( a_vid, b_vid) ;
355
- changed |= edge_changed;
356
- if !retain {
357
- let changed = killed_indices. insert ( index) ;
358
- debug_assert ! ( changed) ;
342
+ match * b_data {
343
+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
344
+ _ => true ,
359
345
}
360
- }
361
- live_indices. subtract ( & killed_indices) ;
362
-
363
- // We could clear `killed_indices` here, but we don't need to and
364
- // it's cheaper not to.
346
+ } ) ;
365
347
}
366
348
}
367
349
368
- // This function is very hot in some workloads. There's a single callsite
369
- // so always inlining is ok even though it's large.
370
- #[ inline( always) ]
371
350
fn expand_node (
372
351
& self ,
373
352
a_region : Region < ' tcx > ,
0 commit comments