@@ -29,6 +29,7 @@ use crate::consumers::ConsumerOptions;
2929use crate :: diagnostics:: RegionErrors ;
3030use crate :: facts:: { AllFacts , AllFactsExt , RustcFacts } ;
3131use crate :: location:: LocationTable ;
32+ use crate :: polonius:: LocalizedOutlivesConstraintSet ;
3233use crate :: region_infer:: RegionInferenceContext ;
3334use crate :: type_check:: { self , MirTypeckResults } ;
3435use crate :: universal_regions:: UniversalRegions ;
@@ -45,6 +46,9 @@ pub(crate) struct NllOutput<'tcx> {
4546 pub polonius_output : Option < Box < PoloniusOutput > > ,
4647 pub opt_closure_req : Option < ClosureRegionRequirements < ' tcx > > ,
4748 pub nll_errors : RegionErrors < ' tcx > ,
49+
50+ /// When using `-Zpolonius=next`: the localized typeck and liveness constraints.
51+ pub localized_outlives_constraints : Option < LocalizedOutlivesConstraintSet > ,
4852}
4953
5054/// 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>(
135139 elements,
136140 ) ;
137141
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+
138151 // If requested: dump NLL facts, and run legacy polonius analysis.
139152 let polonius_output = all_facts. as_ref ( ) . and_then ( |all_facts| {
140153 if infcx. tcx . sess . opts . unstable_opts . nll_facts {
@@ -175,6 +188,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
175188 polonius_output,
176189 opt_closure_req : closure_region_requirements,
177190 nll_errors,
191+ localized_outlives_constraints,
178192 }
179193}
180194
@@ -215,40 +229,7 @@ pub(super) fn dump_nll_mir<'tcx>(
215229 & 0 ,
216230 body,
217231 |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)
252233 } ,
253234 options,
254235 ) ;
@@ -266,6 +247,51 @@ pub(super) fn dump_nll_mir<'tcx>(
266247 } ;
267248}
268249
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+
269295#[ allow( rustc:: diagnostic_outside_of_impl) ]
270296#[ allow( rustc:: untranslatable_diagnostic) ]
271297pub ( super ) fn dump_annotation < ' tcx , ' infcx > (
0 commit comments