1
1
use crate :: borrow_check:: borrow_set:: BorrowSet ;
2
- use crate :: borrow_check:: location:: { LocationIndex , LocationTable } ;
2
+ use crate :: borrow_check:: location:: LocationTable ;
3
3
use crate :: borrow_check:: nll:: facts:: AllFactsExt ;
4
4
use crate :: borrow_check:: nll:: type_check:: { MirTypeckResults , MirTypeckRegionConstraints } ;
5
5
use crate :: borrow_check:: nll:: region_infer:: values:: RegionValueElements ;
6
- use crate :: dataflow:: indexes:: BorrowIndex ;
7
- use crate :: dataflow:: move_paths:: { InitLocation , MoveData , MovePathIndex , InitKind } ;
6
+ use crate :: dataflow:: move_paths:: { InitLocation , MoveData , InitKind } ;
8
7
use crate :: dataflow:: FlowAtLocation ;
9
8
use crate :: dataflow:: MaybeInitializedPlaces ;
10
9
use crate :: transform:: MirSource ;
@@ -43,10 +42,12 @@ crate mod universal_regions;
43
42
crate mod type_check;
44
43
crate mod region_infer;
45
44
46
- use self :: facts:: AllFacts ;
45
+ use self :: facts:: { AllFacts , RustcFacts } ;
47
46
use self :: region_infer:: RegionInferenceContext ;
48
47
use self :: universal_regions:: UniversalRegions ;
49
48
49
+ crate type PoloniusOutput = Output < RustcFacts > ;
50
+
50
51
/// Rewrites the regions in the MIR to use NLL variables, also
51
52
/// scraping out the set of universal regions (e.g., region parameters)
52
53
/// declared on the function. That set will need to be given to
@@ -170,7 +171,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
170
171
errors_buffer : & mut Vec < Diagnostic > ,
171
172
) -> (
172
173
RegionInferenceContext < ' tcx > ,
173
- Option < Rc < Output < RegionVid , BorrowIndex , LocationIndex , Local , MovePathIndex > > > ,
174
+ Option < Rc < PoloniusOutput > > ,
174
175
Option < ClosureRegionRequirements < ' tcx > > ,
175
176
) {
176
177
let mut all_facts = AllFacts :: enabled ( infcx. tcx ) . then_some ( AllFacts :: default ( ) ) ;
@@ -204,6 +205,39 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
204
205
. universal_region
205
206
. extend ( universal_regions. universal_regions ( ) ) ;
206
207
populate_polonius_move_facts ( all_facts, move_data, location_table, & body) ;
208
+
209
+ // Emit universal regions facts, and their relations, for Polonius.
210
+ //
211
+ // 1: universal regions are modeled in Polonius as a pair:
212
+ // - the universal region vid itself.
213
+ // - a "placeholder loan" associated to this universal region. Since they don't exist in
214
+ // the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
215
+ // added to the existing number of loans, as if they succeeded them in the set.
216
+ //
217
+ let borrow_count = borrow_set. borrows . len ( ) ;
218
+ debug ! (
219
+ "compute_regions: polonius placeholders, num_universals={}, borrow_count={}" ,
220
+ universal_regions. len( ) ,
221
+ borrow_count
222
+ ) ;
223
+
224
+ for universal_region in universal_regions. universal_regions ( ) {
225
+ let universal_region_idx = universal_region. index ( ) ;
226
+ let placeholder_loan_idx = borrow_count + universal_region_idx;
227
+ all_facts. placeholder . push ( ( universal_region, placeholder_loan_idx. into ( ) ) ) ;
228
+ }
229
+
230
+ // 2: the universal region relations `outlives` constraints are emitted as
231
+ // `known_subset` facts.
232
+ for ( fr1, fr2) in universal_region_relations. known_outlives ( ) {
233
+ if fr1 != fr2 {
234
+ debug ! (
235
+ "compute_regions: emitting polonius `known_subset` fr1={:?}, fr2={:?}" ,
236
+ fr1, fr2
237
+ ) ;
238
+ all_facts. known_subset . push ( ( * fr1, * fr2) ) ;
239
+ }
240
+ }
207
241
}
208
242
209
243
// Create the region inference context, taking ownership of the
@@ -265,7 +299,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
265
299
266
300
if infcx. tcx . sess . opts . debugging_opts . polonius {
267
301
let algorithm = env:: var ( "POLONIUS_ALGORITHM" )
268
- . unwrap_or_else ( |_| String :: from ( "Hybrid " ) ) ;
302
+ . unwrap_or_else ( |_| String :: from ( "Naive " ) ) ;
269
303
let algorithm = Algorithm :: from_str ( & algorithm) . unwrap ( ) ;
270
304
debug ! ( "compute_regions: using polonius algorithm {:?}" , algorithm) ;
271
305
Some ( Rc :: new ( Output :: compute (
@@ -279,8 +313,15 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
279
313
} ) ;
280
314
281
315
// Solve the region constraints.
282
- let closure_region_requirements =
283
- regioncx. solve ( infcx, & body, local_names, upvars, def_id, errors_buffer) ;
316
+ let closure_region_requirements = regioncx. solve (
317
+ infcx,
318
+ & body,
319
+ local_names,
320
+ upvars,
321
+ def_id,
322
+ errors_buffer,
323
+ polonius_output. clone ( ) ,
324
+ ) ;
284
325
285
326
// Dump MIR results into a file, if that is enabled. This let us
286
327
// write unit-tests, as well as helping with debugging.
0 commit comments