11use std:: fmt;
22
3+ use either:: Either ;
34use rustc_data_structures:: fx:: FxIndexMap ;
45use rustc_index:: bit_set:: { DenseBitSet , MixedBitSet } ;
56use rustc_middle:: mir:: {
@@ -11,10 +12,13 @@ use rustc_mir_dataflow::impls::{
1112 EverInitializedPlaces , EverInitializedPlacesDomain , MaybeUninitializedPlaces ,
1213 MaybeUninitializedPlacesDomain ,
1314} ;
15+ use rustc_mir_dataflow:: points:: { DenseLocationMap , PointIndex } ;
1416use rustc_mir_dataflow:: { Analysis , GenKill , JoinSemiLattice } ;
1517use tracing:: debug;
1618
17- use crate :: { BorrowSet , PlaceConflictBias , PlaceExt , RegionInferenceContext , places_conflict} ;
19+ use crate :: polonius:: { self , LiveLoans } ;
20+ use crate :: region_infer:: InferredRegions ;
21+ use crate :: { BorrowSet , PlaceConflictBias , PlaceExt , places_conflict} ;
1822
1923// This analysis is different to most others. Its results aren't computed with
2024// `iterate_to_fixpoint`, but are instead composed from the results of three sub-analyses that are
@@ -182,34 +186,33 @@ struct OutOfScopePrecomputer<'a, 'tcx> {
182186 visited : DenseBitSet < mir:: BasicBlock > ,
183187 visit_stack : Vec < mir:: BasicBlock > ,
184188 body : & ' a Body < ' tcx > ,
185- regioncx : & ' a RegionInferenceContext < ' tcx > ,
186189 borrows_out_of_scope_at_location : FxIndexMap < Location , Vec < BorrowIndex > > ,
187190}
188191
189192impl < ' tcx > OutOfScopePrecomputer < ' _ , ' tcx > {
190193 fn compute (
191194 body : & Body < ' tcx > ,
192- regioncx : & RegionInferenceContext < ' tcx > ,
195+ scc_values : & InferredRegions < ' _ > ,
193196 borrow_set : & BorrowSet < ' tcx > ,
194197 ) -> FxIndexMap < Location , Vec < BorrowIndex > > {
195198 let mut prec = OutOfScopePrecomputer {
196199 visited : DenseBitSet :: new_empty ( body. basic_blocks . len ( ) ) ,
197200 visit_stack : vec ! [ ] ,
198201 body,
199- regioncx,
200202 borrows_out_of_scope_at_location : FxIndexMap :: default ( ) ,
201203 } ;
202204 for ( borrow_index, borrow_data) in borrow_set. iter_enumerated ( ) {
203205 let borrow_region = borrow_data. region ;
204206 let location = borrow_data. reserve_location ;
205- prec. precompute_borrows_out_of_scope ( borrow_index, borrow_region, location) ;
207+ prec. precompute_borrows_out_of_scope ( scc_values , borrow_index, borrow_region, location) ;
206208 }
207209
208210 prec. borrows_out_of_scope_at_location
209211 }
210212
211213 fn precompute_borrows_out_of_scope (
212214 & mut self ,
215+ scc_values : & InferredRegions < ' _ > ,
213216 borrow_index : BorrowIndex ,
214217 borrow_region : RegionVid ,
215218 first_location : Location ,
@@ -222,12 +225,9 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
222225 let first_lo = first_location. statement_index ;
223226 let first_hi = first_bb_data. statements . len ( ) ;
224227
225- if let Some ( kill_stmt) = self . regioncx . first_non_contained_inclusive (
226- borrow_region,
227- first_block,
228- first_lo,
229- first_hi,
230- ) {
228+ if let Some ( kill_stmt) =
229+ scc_values. first_non_contained_inclusive ( borrow_region, first_block, first_lo, first_hi)
230+ {
231231 let kill_location = Location { block : first_block, statement_index : kill_stmt } ;
232232 // If region does not contain a point at the location, then add to list and skip
233233 // successor locations.
@@ -255,7 +255,7 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
255255 let bb_data = & self . body [ block] ;
256256 let num_stmts = bb_data. statements . len ( ) ;
257257 if let Some ( kill_stmt) =
258- self . regioncx . first_non_contained_inclusive ( borrow_region, block, 0 , num_stmts)
258+ scc_values . first_non_contained_inclusive ( borrow_region, block, 0 , num_stmts)
259259 {
260260 let kill_location = Location { block, statement_index : kill_stmt } ;
261261 // If region does not contain a point at the location, then add to list and skip
@@ -285,25 +285,26 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
285285// This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
286286pub fn calculate_borrows_out_of_scope_at_location < ' tcx > (
287287 body : & Body < ' tcx > ,
288- regioncx : & RegionInferenceContext < ' tcx > ,
288+ scc_values : & InferredRegions < ' _ > ,
289289 borrow_set : & BorrowSet < ' tcx > ,
290290) -> FxIndexMap < Location , Vec < BorrowIndex > > {
291- OutOfScopePrecomputer :: compute ( body, regioncx , borrow_set)
291+ OutOfScopePrecomputer :: compute ( body, scc_values , borrow_set)
292292}
293293
294294struct PoloniusOutOfScopePrecomputer < ' a , ' tcx > {
295295 visited : DenseBitSet < mir:: BasicBlock > ,
296296 visit_stack : Vec < mir:: BasicBlock > ,
297297 body : & ' a Body < ' tcx > ,
298- regioncx : & ' a RegionInferenceContext < ' tcx > ,
299-
298+ live_loans : & ' a LiveLoans ,
299+ location_map : & ' a DenseLocationMap ,
300300 loans_out_of_scope_at_location : FxIndexMap < Location , Vec < BorrowIndex > > ,
301301}
302302
303303impl < ' tcx > PoloniusOutOfScopePrecomputer < ' _ , ' tcx > {
304304 fn compute (
305305 body : & Body < ' tcx > ,
306- regioncx : & RegionInferenceContext < ' tcx > ,
306+ location_map : & DenseLocationMap ,
307+ live_loans : & LiveLoans ,
307308 borrow_set : & BorrowSet < ' tcx > ,
308309 ) -> FxIndexMap < Location , Vec < BorrowIndex > > {
309310 // The in-tree polonius analysis computes loans going out of scope using the
@@ -312,7 +313,8 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
312313 visited : DenseBitSet :: new_empty ( body. basic_blocks . len ( ) ) ,
313314 visit_stack : vec ! [ ] ,
314315 body,
315- regioncx,
316+ live_loans,
317+ location_map,
316318 loans_out_of_scope_at_location : FxIndexMap :: default ( ) ,
317319 } ;
318320 for ( loan_idx, loan_data) in borrow_set. iter_enumerated ( ) {
@@ -412,7 +414,8 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
412414 // Reachability is location-insensitive, and we could take advantage of that, by jumping
413415 // to a further point than just the next statement: we can jump to the furthest point
414416 // within the block where `r` is live.
415- if self . regioncx . is_loan_live_at ( loan_idx, location) {
417+ let point = self . location_map . point_from_location ( location) ;
418+ if self . is_loan_live_at ( loan_idx, point) {
416419 continue ;
417420 }
418421
@@ -423,21 +426,28 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
423426
424427 None
425428 }
429+
430+ fn is_loan_live_at ( & self , loan_idx : BorrowIndex , point : PointIndex ) -> bool {
431+ self . live_loans . contains ( point, loan_idx)
432+ }
426433}
427434
428435impl < ' a , ' tcx > Borrows < ' a , ' tcx > {
429436 pub fn new (
430437 tcx : TyCtxt < ' tcx > ,
431438 body : & ' a Body < ' tcx > ,
432- regioncx : & RegionInferenceContext < ' tcx > ,
439+ inference_results : Either < & ' a InferredRegions < ' _ > , & ' a polonius:: LiveLoans > ,
440+ location_map : & DenseLocationMap ,
433441 borrow_set : & ' a BorrowSet < ' tcx > ,
434442 ) -> Self {
435- let borrows_out_of_scope_at_location =
436- if !tcx. sess . opts . unstable_opts . polonius . is_next_enabled ( ) {
437- calculate_borrows_out_of_scope_at_location ( body, regioncx, borrow_set)
438- } else {
439- PoloniusOutOfScopePrecomputer :: compute ( body, regioncx, borrow_set)
440- } ;
443+ let borrows_out_of_scope_at_location = match inference_results {
444+ Either :: Left ( inferred_regions) => {
445+ calculate_borrows_out_of_scope_at_location ( body, inferred_regions, borrow_set)
446+ }
447+ Either :: Right ( live_loans) => {
448+ PoloniusOutOfScopePrecomputer :: compute ( body, location_map, live_loans, borrow_set)
449+ }
450+ } ;
441451 Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
442452 }
443453
0 commit comments