@@ -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;
@@ -295,62 +294,59 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
295294 }
296295
297296 fn expansion ( & self , var_values : & mut LexicalRegionResolutions < ' tcx > ) {
298- let mut process_constraint = |constraint : & Constraint < ' tcx > | {
299- let ( a_region, b_vid, b_data, retain) = match * constraint {
297+ let mut constraints = IndexVec :: from_elem_n ( Vec :: new ( ) , var_values. values . len ( ) ) ;
298+ let mut changes = Vec :: new ( ) ;
299+ for constraint in self . data . constraints . keys ( ) {
300+ let ( a_vid, a_region, b_vid, b_data) = match * constraint {
300301 Constraint :: RegSubVar ( a_region, b_vid) => {
301302 let b_data = var_values. value_mut ( b_vid) ;
302- ( a_region, b_vid, b_data, false )
303+ ( None , a_region, b_vid, b_data)
303304 }
304305 Constraint :: VarSubVar ( a_vid, b_vid) => match * var_values. value ( a_vid) {
305- VarValue :: ErrorValue => return ( false , false ) ,
306+ VarValue :: ErrorValue => continue ,
306307 VarValue :: Value ( a_region) => {
307308 let b_data = var_values. value_mut ( b_vid) ;
308- let retain = match * b_data {
309- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
310- _ => true ,
311- } ;
312- ( a_region, b_vid, b_data, retain)
309+ ( Some ( a_vid) , a_region, b_vid, b_data)
313310 }
314311 } ,
315312 Constraint :: RegSubReg ( ..) | Constraint :: VarSubReg ( ..) => {
316313 // These constraints are checked after expansion
317314 // is done, in `collect_errors`.
318- return ( false , false ) ;
315+ continue ;
319316 }
320317 } ;
321-
322- let changed = self . expand_node ( a_region, b_vid, b_data) ;
323- ( changed, retain)
324- } ;
325-
326- // Using bitsets to track the remaining elements is faster than using a
327- // `Vec` by itself (which requires removing elements, which requires
328- // element shuffling, which is slow).
329- let constraints: Vec < _ > = self . data . constraints . keys ( ) . collect ( ) ;
330- let mut live_indices: BitSet < usize > = BitSet :: new_filled ( constraints. len ( ) ) ;
331- let mut killed_indices: BitSet < usize > = BitSet :: new_empty ( constraints. len ( ) ) ;
332- let mut changed = true ;
333- while changed {
334- changed = false ;
335- for index in live_indices. iter ( ) {
336- let constraint = constraints[ index] ;
337- let ( edge_changed, retain) = process_constraint ( constraint) ;
338- changed |= edge_changed;
339- if !retain {
340- let changed = killed_indices. insert ( index) ;
341- debug_assert ! ( changed) ;
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+ }
342328 }
343329 }
344- live_indices . subtract ( & killed_indices ) ;
330+ }
345331
346- // We could clear `killed_indices` here, but we don't need to and
347- // it's cheaper not to.
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) ;
341+ }
342+ match * b_data {
343+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
344+ _ => true ,
345+ }
346+ } ) ;
348347 }
349348 }
350349
351- // This function is very hot in some workloads. There's a single callsite
352- // so always inlining is ok even though it's large.
353- #[ inline( always) ]
354350 fn expand_node (
355351 & self ,
356352 a_region : Region < ' tcx > ,
@@ -790,8 +786,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
790786 self . var_infos [ node_idx] . origin . span ( ) ,
791787 & format ! (
792788 "collect_error_for_expanding_node() could not find \
793- error for var {:?} in universe {:?}, lower_bounds={:#?}, \
794- upper_bounds={:#?}",
789+ error for var {:?} in universe {:?}, lower_bounds={:#?}, \
790+ upper_bounds={:#?}",
795791 node_idx, node_universe, lower_bounds, upper_bounds
796792 ) ,
797793 ) ;
0 commit comments