@@ -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