@@ -29,6 +29,7 @@ use crate::consumers::ConsumerOptions;
29
29
use crate :: diagnostics:: RegionErrors ;
30
30
use crate :: facts:: { AllFacts , AllFactsExt , RustcFacts } ;
31
31
use crate :: location:: LocationTable ;
32
+ use crate :: polonius:: LocalizedOutlivesConstraintSet ;
32
33
use crate :: region_infer:: RegionInferenceContext ;
33
34
use crate :: type_check:: { self , MirTypeckResults } ;
34
35
use crate :: universal_regions:: UniversalRegions ;
@@ -45,6 +46,9 @@ pub(crate) struct NllOutput<'tcx> {
45
46
pub polonius_output : Option < Box < PoloniusOutput > > ,
46
47
pub opt_closure_req : Option < ClosureRegionRequirements < ' tcx > > ,
47
48
pub nll_errors : RegionErrors < ' tcx > ,
49
+
50
+ /// When using `-Zpolonius=next`: the localized typeck and liveness constraints.
51
+ pub localized_outlives_constraints : Option < LocalizedOutlivesConstraintSet > ,
48
52
}
49
53
50
54
/// Rewrites the regions in the MIR to use NLL variables, also scraping out the set of universal
@@ -135,6 +139,15 @@ pub(crate) fn compute_regions<'a, 'tcx>(
135
139
elements,
136
140
) ;
137
141
142
+ // If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives
143
+ // constraints.
144
+ let localized_outlives_constraints =
145
+ if infcx. tcx . sess . opts . unstable_opts . polonius . is_next_enabled ( ) {
146
+ Some ( polonius:: create_localized_constraints ( & mut regioncx, body) )
147
+ } else {
148
+ None
149
+ } ;
150
+
138
151
// If requested: dump NLL facts, and run legacy polonius analysis.
139
152
let polonius_output = all_facts. as_ref ( ) . and_then ( |all_facts| {
140
153
if infcx. tcx . sess . opts . unstable_opts . nll_facts {
@@ -175,6 +188,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
175
188
polonius_output,
176
189
opt_closure_req : closure_region_requirements,
177
190
nll_errors,
191
+ localized_outlives_constraints,
178
192
}
179
193
}
180
194
@@ -215,40 +229,7 @@ pub(super) fn dump_nll_mir<'tcx>(
215
229
& 0 ,
216
230
body,
217
231
|pass_where, out| {
218
- match pass_where {
219
- // Before the CFG, dump out the values for each region variable.
220
- PassWhere :: BeforeCFG => {
221
- regioncx. dump_mir ( tcx, out) ?;
222
- writeln ! ( out, "|" ) ?;
223
-
224
- if let Some ( closure_region_requirements) = closure_region_requirements {
225
- writeln ! ( out, "| Free Region Constraints" ) ?;
226
- for_each_region_constraint ( tcx, closure_region_requirements, & mut |msg| {
227
- writeln ! ( out, "| {msg}" )
228
- } ) ?;
229
- writeln ! ( out, "|" ) ?;
230
- }
231
-
232
- if borrow_set. len ( ) > 0 {
233
- writeln ! ( out, "| Borrows" ) ?;
234
- for ( borrow_idx, borrow_data) in borrow_set. iter_enumerated ( ) {
235
- writeln ! (
236
- out,
237
- "| {:?}: issued at {:?} in {:?}" ,
238
- borrow_idx, borrow_data. reserve_location, borrow_data. region
239
- ) ?;
240
- }
241
- writeln ! ( out, "|" ) ?;
242
- }
243
- }
244
-
245
- PassWhere :: BeforeLocation ( _) => { }
246
-
247
- PassWhere :: AfterTerminator ( _) => { }
248
-
249
- PassWhere :: BeforeBlock ( _) | PassWhere :: AfterLocation ( _) | PassWhere :: AfterCFG => { }
250
- }
251
- Ok ( ( ) )
232
+ emit_nll_mir ( tcx, regioncx, closure_region_requirements, borrow_set, pass_where, out)
252
233
} ,
253
234
options,
254
235
) ;
@@ -266,6 +247,51 @@ pub(super) fn dump_nll_mir<'tcx>(
266
247
} ;
267
248
}
268
249
250
+ /// Produces the actual NLL MIR sections to emit during the dumping process.
251
+ pub ( crate ) fn emit_nll_mir < ' tcx > (
252
+ tcx : TyCtxt < ' tcx > ,
253
+ regioncx : & RegionInferenceContext < ' tcx > ,
254
+ closure_region_requirements : & Option < ClosureRegionRequirements < ' tcx > > ,
255
+ borrow_set : & BorrowSet < ' tcx > ,
256
+ pass_where : PassWhere ,
257
+ out : & mut dyn io:: Write ,
258
+ ) -> io:: Result < ( ) > {
259
+ match pass_where {
260
+ // Before the CFG, dump out the values for each region variable.
261
+ PassWhere :: BeforeCFG => {
262
+ regioncx. dump_mir ( tcx, out) ?;
263
+ writeln ! ( out, "|" ) ?;
264
+
265
+ if let Some ( closure_region_requirements) = closure_region_requirements {
266
+ writeln ! ( out, "| Free Region Constraints" ) ?;
267
+ for_each_region_constraint ( tcx, closure_region_requirements, & mut |msg| {
268
+ writeln ! ( out, "| {msg}" )
269
+ } ) ?;
270
+ writeln ! ( out, "|" ) ?;
271
+ }
272
+
273
+ if borrow_set. len ( ) > 0 {
274
+ writeln ! ( out, "| Borrows" ) ?;
275
+ for ( borrow_idx, borrow_data) in borrow_set. iter_enumerated ( ) {
276
+ writeln ! (
277
+ out,
278
+ "| {:?}: issued at {:?} in {:?}" ,
279
+ borrow_idx, borrow_data. reserve_location, borrow_data. region
280
+ ) ?;
281
+ }
282
+ writeln ! ( out, "|" ) ?;
283
+ }
284
+ }
285
+
286
+ PassWhere :: BeforeLocation ( _) => { }
287
+
288
+ PassWhere :: AfterTerminator ( _) => { }
289
+
290
+ PassWhere :: BeforeBlock ( _) | PassWhere :: AfterLocation ( _) | PassWhere :: AfterCFG => { }
291
+ }
292
+ Ok ( ( ) )
293
+ }
294
+
269
295
#[ allow( rustc:: diagnostic_outside_of_impl) ]
270
296
#[ allow( rustc:: untranslatable_diagnostic) ]
271
297
pub ( super ) fn dump_annotation < ' tcx , ' infcx > (
0 commit comments