@@ -187,19 +187,28 @@ struct OutOfScopePrecomputer<'a, 'tcx> {
187187 borrows_out_of_scope_at_location : FxIndexMap < Location , Vec < BorrowIndex > > ,
188188}
189189
190- impl < ' a , ' tcx > OutOfScopePrecomputer < ' a , ' tcx > {
191- fn new ( body : & ' a Body < ' tcx > , regioncx : & ' a RegionInferenceContext < ' tcx > ) -> Self {
192- OutOfScopePrecomputer {
190+ impl < ' tcx > OutOfScopePrecomputer < ' _ , ' tcx > {
191+ fn compute (
192+ body : & Body < ' tcx > ,
193+ regioncx : & RegionInferenceContext < ' tcx > ,
194+ borrow_set : & BorrowSet < ' tcx > ,
195+ ) -> FxIndexMap < Location , Vec < BorrowIndex > > {
196+ let mut prec = OutOfScopePrecomputer {
193197 visited : DenseBitSet :: new_empty ( body. basic_blocks . len ( ) ) ,
194198 visit_stack : vec ! [ ] ,
195199 body,
196200 regioncx,
197201 borrows_out_of_scope_at_location : FxIndexMap :: default ( ) ,
202+ } ;
203+ for ( borrow_index, borrow_data) in borrow_set. iter_enumerated ( ) {
204+ let borrow_region = borrow_data. region ;
205+ let location = borrow_data. reserve_location ;
206+ prec. precompute_borrows_out_of_scope ( borrow_index, borrow_region, location) ;
198207 }
208+
209+ prec. borrows_out_of_scope_at_location
199210 }
200- }
201211
202- impl < ' tcx > OutOfScopePrecomputer < ' _ , ' tcx > {
203212 fn precompute_borrows_out_of_scope (
204213 & mut self ,
205214 borrow_index : BorrowIndex ,
@@ -280,15 +289,7 @@ pub fn calculate_borrows_out_of_scope_at_location<'tcx>(
280289 regioncx : & RegionInferenceContext < ' tcx > ,
281290 borrow_set : & BorrowSet < ' tcx > ,
282291) -> FxIndexMap < Location , Vec < BorrowIndex > > {
283- let mut prec = OutOfScopePrecomputer :: new ( body, regioncx) ;
284- for ( borrow_index, borrow_data) in borrow_set. iter_enumerated ( ) {
285- let borrow_region = borrow_data. region ;
286- let location = borrow_data. reserve_location ;
287-
288- prec. precompute_borrows_out_of_scope ( borrow_index, borrow_region, location) ;
289- }
290-
291- prec. borrows_out_of_scope_at_location
292+ OutOfScopePrecomputer :: compute ( body, regioncx, borrow_set)
292293}
293294
294295struct PoloniusOutOfScopePrecomputer < ' a , ' tcx > {
@@ -300,19 +301,30 @@ struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
300301 loans_out_of_scope_at_location : FxIndexMap < Location , Vec < BorrowIndex > > ,
301302}
302303
303- impl < ' a , ' tcx > PoloniusOutOfScopePrecomputer < ' a , ' tcx > {
304- fn new ( body : & ' a Body < ' tcx > , regioncx : & ' a RegionInferenceContext < ' tcx > ) -> Self {
305- Self {
304+ impl < ' tcx > PoloniusOutOfScopePrecomputer < ' _ , ' tcx > {
305+ fn compute (
306+ body : & Body < ' tcx > ,
307+ regioncx : & RegionInferenceContext < ' tcx > ,
308+ borrow_set : & BorrowSet < ' tcx > ,
309+ ) -> FxIndexMap < Location , Vec < BorrowIndex > > {
310+ // The in-tree polonius analysis computes loans going out of scope using the
311+ // set-of-loans model.
312+ let mut prec = PoloniusOutOfScopePrecomputer {
306313 visited : DenseBitSet :: new_empty ( body. basic_blocks . len ( ) ) ,
307314 visit_stack : vec ! [ ] ,
308315 body,
309316 regioncx,
310317 loans_out_of_scope_at_location : FxIndexMap :: default ( ) ,
318+ } ;
319+ for ( loan_idx, loan_data) in borrow_set. iter_enumerated ( ) {
320+ let issuing_region = loan_data. region ;
321+ let loan_issued_at = loan_data. reserve_location ;
322+ prec. precompute_loans_out_of_scope ( loan_idx, issuing_region, loan_issued_at) ;
311323 }
324+
325+ prec. loans_out_of_scope_at_location
312326 }
313- }
314327
315- impl < ' tcx > PoloniusOutOfScopePrecomputer < ' _ , ' tcx > {
316328 /// Loans are in scope while they are live: whether they are contained within any live region.
317329 /// In the location-insensitive analysis, a loan will be contained in a region if the issuing
318330 /// region can reach it in the subset graph. So this is a reachability problem.
@@ -325,10 +337,17 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
325337 let sccs = self . regioncx . constraint_sccs ( ) ;
326338 let universal_regions = self . regioncx . universal_regions ( ) ;
327339
340+ // The loop below was useful for the location-insensitive analysis but shouldn't be
341+ // impactful in the location-sensitive case. It seems that it does, however, as without it a
342+ // handful of tests fail. That likely means some liveness or outlives data related to choice
343+ // regions is missing
344+ // FIXME: investigate the impact of loans traversing applied member constraints and why some
345+ // tests fail otherwise.
346+ //
328347 // We first handle the cases where the loan doesn't go out of scope, depending on the
329348 // issuing region's successors.
330349 for successor in graph:: depth_first_search ( & self . regioncx . region_graph ( ) , issuing_region) {
331- // 1. Via applied member constraints
350+ // Via applied member constraints
332351 //
333352 // The issuing region can flow into the choice regions, and they are either:
334353 // - placeholders or free regions themselves,
@@ -346,14 +365,6 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
346365 return ;
347366 }
348367 }
349-
350- // 2. Via regions that are live at all points: placeholders and free regions.
351- //
352- // If the issuing region outlives such a region, its loan escapes the function and
353- // cannot go out of scope. We can early return.
354- if self . regioncx . is_region_live_at_all_points ( successor) {
355- return ;
356- }
357368 }
358369
359370 let first_block = loan_issued_at. block ;
@@ -461,34 +472,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
461472 regioncx : & RegionInferenceContext < ' tcx > ,
462473 borrow_set : & ' a BorrowSet < ' tcx > ,
463474 ) -> Self {
464- let mut borrows_out_of_scope_at_location =
465- calculate_borrows_out_of_scope_at_location ( body, regioncx, borrow_set) ;
466-
467- // The in-tree polonius analysis computes loans going out of scope using the set-of-loans
468- // model, and makes sure they're identical to the existing computation of the set-of-points
469- // model.
470- if tcx. sess . opts . unstable_opts . polonius . is_next_enabled ( ) {
471- let mut polonius_prec = PoloniusOutOfScopePrecomputer :: new ( body, regioncx) ;
472- for ( loan_idx, loan_data) in borrow_set. iter_enumerated ( ) {
473- let issuing_region = loan_data. region ;
474- let loan_issued_at = loan_data. reserve_location ;
475-
476- polonius_prec. precompute_loans_out_of_scope (
477- loan_idx,
478- issuing_region,
479- loan_issued_at,
480- ) ;
481- }
482-
483- assert_eq ! (
484- borrows_out_of_scope_at_location, polonius_prec. loans_out_of_scope_at_location,
485- "polonius loan scopes differ from NLL borrow scopes, for body {:?}" ,
486- body. span,
487- ) ;
488-
489- borrows_out_of_scope_at_location = polonius_prec. loans_out_of_scope_at_location ;
490- }
491-
475+ let borrows_out_of_scope_at_location =
476+ if !tcx. sess . opts . unstable_opts . polonius . is_next_enabled ( ) {
477+ calculate_borrows_out_of_scope_at_location ( body, regioncx, borrow_set)
478+ } else {
479+ PoloniusOutOfScopePrecomputer :: compute ( body, regioncx, borrow_set)
480+ } ;
492481 Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
493482 }
494483
0 commit comments