Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1331ccb

Browse files
committed
introduce beginnings of polonius MIR dump
This is mostly for test purposes to show the localized constraints until the MIR debugger is set up.
1 parent 7a81cad commit 1331ccb

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,16 @@ fn do_mir_borrowck<'tcx>(
319319

320320
mbcx.report_move_errors();
321321

322+
// If requested, dump polonius MIR.
323+
polonius::dump_polonius_mir(
324+
&infcx,
325+
body,
326+
&regioncx,
327+
&borrow_set,
328+
&localized_outlives_constraints,
329+
&opt_closure_req,
330+
);
331+
322332
// For each non-user used mutable variable, check if it's been assigned from
323333
// a user-declared local. If so, then put that local into the used_mut set.
324334
// Note that this set is expected to be small - only upvars from closures
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use std::io;
2+
3+
use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options};
4+
use rustc_middle::mir::{Body, ClosureRegionRequirements, PassWhere};
5+
use rustc_middle::ty::TyCtxt;
6+
use rustc_session::config::MirIncludeSpans;
7+
8+
use crate::borrow_set::BorrowSet;
9+
use crate::polonius::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet};
10+
use crate::{BorrowckInferCtxt, RegionInferenceContext};
11+
12+
/// `-Zdump-mir=polonius` dumps MIR annotated with NLL and polonius specific information.
13+
// Note: this currently duplicates most of NLL MIR, with some additions for the localized outlives
14+
// constraints. This is ok for now as this dump will change in the near future to an HTML file to
15+
// become more useful.
16+
pub(crate) fn dump_polonius_mir<'tcx>(
17+
infcx: &BorrowckInferCtxt<'tcx>,
18+
body: &Body<'tcx>,
19+
regioncx: &RegionInferenceContext<'tcx>,
20+
borrow_set: &BorrowSet<'tcx>,
21+
localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
22+
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
23+
) {
24+
let tcx = infcx.tcx;
25+
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
26+
return;
27+
}
28+
29+
// We want the NLL extra comments printed by default in NLL MIR dumps (they were removed in
30+
// #112346). Specifying `-Z mir-include-spans` on the CLI still has priority: for example,
31+
// they're always disabled in mir-opt tests to make working with blessed dumps easier.
32+
let options = PrettyPrintMirOptions {
33+
include_extra_comments: matches!(
34+
tcx.sess.opts.unstable_opts.mir_include_spans,
35+
MirIncludeSpans::On | MirIncludeSpans::Nll
36+
),
37+
};
38+
39+
dump_mir_with_options(
40+
tcx,
41+
false,
42+
"polonius",
43+
&0,
44+
body,
45+
|pass_where, out| {
46+
emit_polonius_mir(
47+
tcx,
48+
regioncx,
49+
closure_region_requirements,
50+
borrow_set,
51+
localized_outlives_constraints,
52+
pass_where,
53+
out,
54+
)
55+
},
56+
options,
57+
);
58+
}
59+
60+
/// Produces the actual NLL + Polonius MIR sections to emit during the dumping process.
61+
fn emit_polonius_mir<'tcx>(
62+
tcx: TyCtxt<'tcx>,
63+
regioncx: &RegionInferenceContext<'tcx>,
64+
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
65+
borrow_set: &BorrowSet<'tcx>,
66+
localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
67+
pass_where: PassWhere,
68+
out: &mut dyn io::Write,
69+
) -> io::Result<()> {
70+
// Emit the regular NLL front-matter
71+
crate::nll::emit_nll_mir(
72+
tcx,
73+
regioncx,
74+
closure_region_requirements,
75+
borrow_set,
76+
pass_where.clone(),
77+
out,
78+
)?;
79+
80+
let liveness = regioncx.liveness_constraints();
81+
82+
// Add localized outlives constraints
83+
match pass_where {
84+
PassWhere::BeforeCFG => {
85+
if localized_outlives_constraints.outlives.len() > 0 {
86+
writeln!(out, "| Localized constraints")?;
87+
88+
for constraint in &localized_outlives_constraints.outlives {
89+
let LocalizedOutlivesConstraint { source, from, target, to } = constraint;
90+
let from = liveness.location_from_point(*from);
91+
let to = liveness.location_from_point(*to);
92+
writeln!(out, "| {source:?} at {from:?} -> {target:?} at {to:?}")?;
93+
}
94+
writeln!(out, "|")?;
95+
}
96+
}
97+
_ => {}
98+
}
99+
100+
Ok(())
101+
}

compiler/rustc_borrowck/src/polonius/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
3636
mod constraints;
3737
pub(crate) use constraints::*;
38+
mod dump;
39+
pub(crate) use dump::dump_polonius_mir;
3840
pub(crate) mod legacy;
3941

4042
use rustc_middle::mir::{Body, Location};

compiler/rustc_borrowck/src/region_infer/values.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ impl LivenessValues {
199199
self.elements.point_from_location(location)
200200
}
201201

202+
#[inline]
203+
pub(crate) fn location_from_point(&self, point: PointIndex) -> Location {
204+
self.elements.to_location(point)
205+
}
206+
202207
/// When using `-Zpolonius=next`, returns whether the `loan_idx` is live at the given `point`.
203208
pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, point: PointIndex) -> bool {
204209
self.loans

0 commit comments

Comments
 (0)