@@ -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,23 +296,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
297296 }
298297
299298 fn expansion ( & self , var_values : & mut LexicalRegionResolutions < ' tcx > ) {
300- let mut changed = false ;
301- let mut constraints = Vec :: new ( ) ;
299+ let mut constraints = IndexVec :: from_elem_n ( Vec :: new ( ) , var_values . values . len ( ) ) ;
300+ let mut changes = Vec :: new ( ) ;
302301 for constraint in self . data . constraints . keys ( ) {
303- let ( a_region, b_vid, b_data) = match * constraint {
302+ let ( a_vid , a_region, b_vid, b_data) = match * constraint {
304303 Constraint :: RegSubVar ( a_region, b_vid) => {
305304 let b_data = var_values. value_mut ( b_vid) ;
306- ( a_region, b_vid, b_data)
305+ ( None , a_region, b_vid, b_data)
307306 }
308307 Constraint :: VarSubVar ( a_vid, b_vid) => match * var_values. value ( a_vid) {
309308 VarValue :: ErrorValue => continue ,
310309 VarValue :: Value ( a_region) => {
311310 let b_data = var_values. value_mut ( b_vid) ;
312- match * b_data {
313- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => ( ) ,
314- _ => constraints. push ( ( a_vid, b_vid) ) ,
315- }
316- ( a_region, b_vid, b_data)
311+ ( Some ( a_vid) , a_region, b_vid, b_data)
317312 }
318313 } ,
319314 Constraint :: RegSubReg ( ..) | Constraint :: VarSubReg ( ..) => {
@@ -322,56 +317,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
322317 continue ;
323318 }
324319 } ;
325- let edge_changed = self . expand_node ( a_region, b_vid, b_data) ;
326- if edge_changed {
327- changed = true
320+ if self . expand_node ( a_region, b_vid, b_data) {
321+ changes. push ( b_vid) ;
328322 }
329- }
330-
331- let mut process_constraint = |a_vid, b_vid| {
332- let ( a_region, b_data, retain) = match * var_values. value ( a_vid) {
333- VarValue :: ErrorValue => return ( false , false ) ,
334- VarValue :: Value ( a_region) => {
335- let b_data = var_values. value_mut ( b_vid) ;
336- let retain = match * b_data {
337- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
338- _ => true ,
339- } ;
340- ( a_region, b_data, retain)
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+ }
341330 }
342- } ;
343- let changed = self . expand_node ( a_region, b_vid, b_data) ;
344- ( changed, retain)
345- } ;
331+ }
332+ }
346333
347- // Using bitsets to track the remaining elements is faster than using a
348- // `Vec` by itself (which requires removing elements, which requires
349- // element shuffling, which is slow).
350- let mut live_indices: BitSet < usize > = BitSet :: new_filled ( constraints. len ( ) ) ;
351- let mut killed_indices: BitSet < usize > = BitSet :: new_empty ( constraints. len ( ) ) ;
352- while changed {
353- changed = false ;
354- for index in live_indices. iter ( ) {
355- let ( a_vid, b_vid) = constraints[ index] ;
356- let ( edge_changed, retain) = process_constraint ( a_vid, b_vid) ;
357- if edge_changed {
358- changed = true
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) ;
359343 }
360- if !retain {
361- let changed = killed_indices . insert ( index ) ;
362- debug_assert ! ( changed ) ;
344+ match * b_data {
345+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
346+ _ => true ,
363347 }
364- }
365- live_indices. subtract ( & killed_indices) ;
366-
367- // We could clear `killed_indices` here, but we don't need to and
368- // it's cheaper not to.
348+ } ) ;
369349 }
370350 }
371351
372- // This function is very hot in some workloads. There's a single callsite
373- // so always inlining is ok even though it's large.
374- #[ inline( always) ]
375352 fn expand_node (
376353 & self ,
377354 a_region : Region < ' tcx > ,
0 commit comments