@@ -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,23 +294,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
295294 }
296295
297296 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 ( ) ;
300299 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 {
302301 Constraint :: RegSubVar ( a_region, b_vid) => {
303302 let b_data = var_values. value_mut ( b_vid) ;
304- ( a_region, b_vid, b_data)
303+ ( None , a_region, b_vid, b_data)
305304 }
306305 Constraint :: VarSubVar ( a_vid, b_vid) => match * var_values. value ( a_vid) {
307306 VarValue :: ErrorValue => continue ,
308307 VarValue :: Value ( a_region) => {
309308 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)
315310 }
316311 } ,
317312 Constraint :: RegSubReg ( ..) | Constraint :: VarSubReg ( ..) => {
@@ -320,54 +315,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
320315 continue ;
321316 }
322317 } ;
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+ }
326329 }
327330 }
328331
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) ;
339341 }
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 ,
359345 }
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+ } ) ;
365347 }
366348 }
367349
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) ]
371350 fn expand_node (
372351 & self ,
373352 a_region : Region < ' tcx > ,
0 commit comments