@@ -13,6 +13,7 @@ use rustc_mir_dataflow::{self, fmt::DebugWithContext, GenKill};
13
13
use rustc_mir_dataflow:: { Analysis , Direction , Results } ;
14
14
use std:: fmt;
15
15
16
+ use crate :: constraints:: ConstraintSccIndex ;
16
17
use crate :: { places_conflict, BorrowSet , PlaceConflictBias , PlaceExt , RegionInferenceContext } ;
17
18
18
19
/// A tuple with named fields that can hold either the results or the transient state of the
@@ -251,6 +252,8 @@ struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
251
252
regioncx : & ' a RegionInferenceContext < ' tcx > ,
252
253
loans_out_of_scope_at_location : FxIndexMap < Location , Vec < BorrowIndex > > ,
253
254
placeholders : Vec < RegionVid > ,
255
+ reachability : BitSet < ConstraintSccIndex > ,
256
+ reachability_stack : Vec < ConstraintSccIndex > ,
254
257
}
255
258
256
259
impl < ' a , ' tcx > PoloniusOutOfScopePrecomputer < ' a , ' tcx > {
@@ -261,7 +264,7 @@ impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> {
261
264
let placeholders = regioncx
262
265
. regions ( )
263
266
. filter ( |& r| {
264
- use rustc_infer:: infer:: * ;
267
+ use rustc_infer:: infer:: { NllRegionVariableOrigin , RegionVariableOrigin } ;
265
268
let origin = regioncx. var_infos [ r] . origin ;
266
269
let is_placeholder = matches ! (
267
270
origin,
@@ -278,6 +281,8 @@ impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> {
278
281
regioncx,
279
282
loans_out_of_scope_at_location : FxIndexMap :: default ( ) ,
280
283
placeholders,
284
+ reachability : BitSet :: new_empty ( regioncx. constraint_sccs . num_sccs ( ) ) ,
285
+ reachability_stack : vec ! [ ] ,
281
286
}
282
287
}
283
288
}
@@ -300,21 +305,19 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
300
305
let liveness = & self . regioncx . liveness_constraints ;
301
306
let sccs = & self . regioncx . constraint_sccs ;
302
307
303
- let mut reachability = BitSet :: new_empty ( sccs. num_sccs ( ) ) ;
304
-
305
308
let issuing_region_scc = sccs. scc ( issuing_region) ;
306
- let mut stack = vec ! [ issuing_region_scc] ;
307
- reachability. insert ( issuing_region_scc) ;
309
+ self . reachability_stack . push ( issuing_region_scc) ;
310
+ self . reachability . insert ( issuing_region_scc) ;
308
311
309
312
let member_constraints = & self . regioncx . member_constraints ;
310
313
311
- while let Some ( scc) = stack . pop ( ) {
314
+ while let Some ( scc) = self . reachability_stack . pop ( ) {
312
315
// Handle successors of this SCC:
313
316
//
314
317
// 1. Push outlives successors to the worklist stack
315
318
for & succ_scc in sccs. successors ( scc) {
316
- if reachability. insert ( succ_scc) {
317
- stack . push ( succ_scc) ;
319
+ if self . reachability . insert ( succ_scc) {
320
+ self . reachability_stack . push ( succ_scc) ;
318
321
}
319
322
}
320
323
@@ -327,6 +330,8 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
327
330
// That is to say, if there are member constraints here, the loan escapes the
328
331
// function and cannot go out of scope. We can early return.
329
332
if member_constraints. indices ( scc) . next ( ) . is_some ( ) {
333
+ self . reachability_stack . clear ( ) ;
334
+ self . reachability . clear ( ) ;
330
335
return ;
331
336
}
332
337
}
@@ -375,7 +380,7 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
375
380
// If a single live region is reachable from the issuing region, then the loan
376
381
// is still live at this point. We can stop checking other live regions at this
377
382
// location, and go to the next location.
378
- if reachability. contains ( live_region_scc) {
383
+ if self . reachability . contains ( live_region_scc) {
379
384
issuing_region_can_reach_live_regions = true ;
380
385
break ;
381
386
}
@@ -423,9 +428,10 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
423
428
}
424
429
}
425
430
426
- assert ! ( self . visit_stack. is_empty( ) , "stack should be empty" ) ;
427
-
428
431
self . visited . clear ( ) ;
432
+ self . reachability . clear ( ) ;
433
+ assert ! ( self . visit_stack. is_empty( ) , "visit stack should be empty" ) ;
434
+ assert ! ( self . reachability_stack. is_empty( ) , "reachablity stack should be empty" ) ;
429
435
}
430
436
}
431
437
0 commit comments