introduce beginnings of polonius MIR dump
This is mostly for test purposes to show the localized constraints until the MIR debugger is set up.
This commit is contained in:
parent
ee93ce9c61
commit
c75c5176c5
4 changed files with 118 additions and 0 deletions
|
@ -316,6 +316,16 @@ fn do_mir_borrowck<'tcx>(
|
|||
|
||||
mbcx.report_move_errors();
|
||||
|
||||
// If requested, dump polonius MIR.
|
||||
polonius::dump_polonius_mir(
|
||||
&infcx,
|
||||
body,
|
||||
®ioncx,
|
||||
&borrow_set,
|
||||
&localized_outlives_constraints,
|
||||
&opt_closure_req,
|
||||
);
|
||||
|
||||
// For each non-user used mutable variable, check if it's been assigned from
|
||||
// a user-declared local. If so, then put that local into the used_mut set.
|
||||
// Note that this set is expected to be small - only upvars from closures
|
||||
|
|
101
compiler/rustc_borrowck/src/polonius/dump.rs
Normal file
101
compiler/rustc_borrowck/src/polonius/dump.rs
Normal file
|
@ -0,0 +1,101 @@
|
|||
use std::io;
|
||||
|
||||
use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options};
|
||||
use rustc_middle::mir::{Body, ClosureRegionRequirements, PassWhere};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::MirIncludeSpans;
|
||||
|
||||
use crate::borrow_set::BorrowSet;
|
||||
use crate::polonius::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet};
|
||||
use crate::{BorrowckInferCtxt, RegionInferenceContext};
|
||||
|
||||
/// `-Zdump-mir=polonius` dumps MIR annotated with NLL and polonius specific information.
|
||||
// Note: this currently duplicates most of NLL MIR, with some additions for the localized outlives
|
||||
// constraints. This is ok for now as this dump will change in the near future to an HTML file to
|
||||
// become more useful.
|
||||
pub(crate) fn dump_polonius_mir<'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
|
||||
) {
|
||||
let tcx = infcx.tcx;
|
||||
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
|
||||
return;
|
||||
}
|
||||
|
||||
// We want the NLL extra comments printed by default in NLL MIR dumps (they were removed in
|
||||
// #112346). Specifying `-Z mir-include-spans` on the CLI still has priority: for example,
|
||||
// they're always disabled in mir-opt tests to make working with blessed dumps easier.
|
||||
let options = PrettyPrintMirOptions {
|
||||
include_extra_comments: matches!(
|
||||
tcx.sess.opts.unstable_opts.mir_include_spans,
|
||||
MirIncludeSpans::On | MirIncludeSpans::Nll
|
||||
),
|
||||
};
|
||||
|
||||
dump_mir_with_options(
|
||||
tcx,
|
||||
false,
|
||||
"polonius",
|
||||
&0,
|
||||
body,
|
||||
|pass_where, out| {
|
||||
emit_polonius_mir(
|
||||
tcx,
|
||||
regioncx,
|
||||
closure_region_requirements,
|
||||
borrow_set,
|
||||
localized_outlives_constraints,
|
||||
pass_where,
|
||||
out,
|
||||
)
|
||||
},
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
/// Produces the actual NLL + Polonius MIR sections to emit during the dumping process.
|
||||
fn emit_polonius_mir<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
|
||||
pass_where: PassWhere,
|
||||
out: &mut dyn io::Write,
|
||||
) -> io::Result<()> {
|
||||
// Emit the regular NLL front-matter
|
||||
crate::nll::emit_nll_mir(
|
||||
tcx,
|
||||
regioncx,
|
||||
closure_region_requirements,
|
||||
borrow_set,
|
||||
pass_where.clone(),
|
||||
out,
|
||||
)?;
|
||||
|
||||
let liveness = regioncx.liveness_constraints();
|
||||
|
||||
// Add localized outlives constraints
|
||||
match pass_where {
|
||||
PassWhere::BeforeCFG => {
|
||||
if localized_outlives_constraints.outlives.len() > 0 {
|
||||
writeln!(out, "| Localized constraints")?;
|
||||
|
||||
for constraint in &localized_outlives_constraints.outlives {
|
||||
let LocalizedOutlivesConstraint { source, from, target, to } = constraint;
|
||||
let from = liveness.location_from_point(*from);
|
||||
let to = liveness.location_from_point(*to);
|
||||
writeln!(out, "| {source:?} at {from:?} -> {target:?} at {to:?}")?;
|
||||
}
|
||||
writeln!(out, "|")?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
mod constraints;
|
||||
pub(crate) use constraints::*;
|
||||
mod dump;
|
||||
pub(crate) use dump::dump_polonius_mir;
|
||||
pub(crate) mod legacy;
|
||||
|
||||
use rustc_middle::mir::{Body, Location};
|
||||
|
|
|
@ -199,6 +199,11 @@ impl LivenessValues {
|
|||
self.elements.point_from_location(location)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn location_from_point(&self, point: PointIndex) -> Location {
|
||||
self.elements.to_location(point)
|
||||
}
|
||||
|
||||
/// When using `-Zpolonius=next`, returns whether the `loan_idx` is live at the given `point`.
|
||||
pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, point: PointIndex) -> bool {
|
||||
self.loans
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue