@@ -19,7 +19,6 @@ use rustc_data_structures::graph::implementation::{
1919 Direction , Graph , NodeIndex , INCOMING , OUTGOING ,
2020} ;
2121use rustc_hir:: def_id:: DefId ;
22- use rustc_index:: bit_set:: BitSet ;
2322use rustc_index:: vec:: { Idx , IndexVec } ;
2423use rustc_span:: Span ;
2524use std:: fmt;
@@ -297,64 +296,59 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
297296 }
298297
299298 fn expansion ( & self , var_values : & mut LexicalRegionResolutions < ' tcx > ) {
300- let mut process_constraint = |constraint : & Constraint < ' tcx > | {
301- let ( a_region, b_vid, b_data, retain) = match * constraint {
299+ let mut constraints = IndexVec :: from_elem_n ( Vec :: new ( ) , var_values. values . len ( ) ) ;
300+ let mut changes = Vec :: new ( ) ;
301+ for constraint in self . data . constraints . keys ( ) {
302+ let ( a_vid, a_region, b_vid, b_data) = match * constraint {
302303 Constraint :: RegSubVar ( a_region, b_vid) => {
303304 let b_data = var_values. value_mut ( b_vid) ;
304- ( a_region, b_vid, b_data, false )
305+ ( None , a_region, b_vid, b_data)
305306 }
306307 Constraint :: VarSubVar ( a_vid, b_vid) => match * var_values. value ( a_vid) {
307- VarValue :: ErrorValue => return ( false , false ) ,
308+ VarValue :: ErrorValue => continue ,
308309 VarValue :: Value ( a_region) => {
309310 let b_data = var_values. value_mut ( b_vid) ;
310- let retain = match * b_data {
311- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
312- _ => true ,
313- } ;
314- ( a_region, b_vid, b_data, retain)
311+ ( Some ( a_vid) , a_region, b_vid, b_data)
315312 }
316313 } ,
317314 Constraint :: RegSubReg ( ..) | Constraint :: VarSubReg ( ..) => {
318315 // These constraints are checked after expansion
319316 // is done, in `collect_errors`.
320- return ( false , false ) ;
317+ continue ;
321318 }
322319 } ;
323-
324- let changed = self . expand_node ( a_region, b_vid, b_data) ;
325- ( changed, retain)
326- } ;
327-
328- // Using bitsets to track the remaining elements is faster than using a
329- // `Vec` by itself (which requires removing elements, which requires
330- // element shuffling, which is slow).
331- let constraints: Vec < _ > = self . data . constraints . keys ( ) . collect ( ) ;
332- let mut live_indices: BitSet < usize > = BitSet :: new_filled ( constraints. len ( ) ) ;
333- let mut killed_indices: BitSet < usize > = BitSet :: new_empty ( constraints. len ( ) ) ;
334- let mut changed = true ;
335- while changed {
336- changed = false ;
337- for index in live_indices. iter ( ) {
338- let constraint = constraints[ index] ;
339- let ( edge_changed, retain) = process_constraint ( constraint) ;
340- if edge_changed {
341- changed = true ;
342- }
343- if !retain {
344- let changed = killed_indices. insert ( index) ;
345- debug_assert ! ( changed) ;
320+ if self . expand_node ( a_region, b_vid, b_data) {
321+ changes. push ( b_vid) ;
322+ }
323+ if let Some ( a_vid) = a_vid {
324+ match * b_data {
325+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => ( ) ,
326+ _ => {
327+ constraints[ a_vid] . push ( ( a_vid, b_vid) ) ;
328+ constraints[ b_vid] . push ( ( a_vid, b_vid) ) ;
329+ }
346330 }
347331 }
348- live_indices . subtract ( & killed_indices ) ;
332+ }
349333
350- // We could clear `killed_indices` here, but we don't need to and
351- // it's cheaper not to.
334+ while let Some ( vid) = changes. pop ( ) {
335+ constraints[ vid] . retain ( |& ( a_vid, b_vid) | {
336+ let a_region = match * var_values. value ( a_vid) {
337+ VarValue :: ErrorValue => return false ,
338+ VarValue :: Value ( a_region) => a_region,
339+ } ;
340+ let b_data = var_values. value_mut ( b_vid) ;
341+ if self . expand_node ( a_region, b_vid, b_data) {
342+ changes. push ( b_vid) ;
343+ }
344+ match * b_data {
345+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
346+ _ => true ,
347+ }
348+ } ) ;
352349 }
353350 }
354351
355- // This function is very hot in some workloads. There's a single callsite
356- // so always inlining is ok even though it's large.
357- #[ inline( always) ]
358352 fn expand_node (
359353 & self ,
360354 a_region : Region < ' tcx > ,
0 commit comments