introduce PrettyPrintMirOptions
for cosmetic MIR dump options
initially starting with `-Z mir-include-spans` because we want them in the NLL mir dump pass
This commit is contained in:
parent
0d634185df
commit
c646b46b52
@ -44,8 +44,9 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||
let _mir_guard = crate::PrintOnPanic(|| {
|
||||
let mut buf = Vec::new();
|
||||
with_no_trimmed_paths!({
|
||||
rustc_middle::mir::pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf)
|
||||
.unwrap();
|
||||
use rustc_middle::mir::pretty;
|
||||
let options = pretty::PrettyPrintMirOptions::from_cli(tcx);
|
||||
pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf, options).unwrap();
|
||||
});
|
||||
String::from_utf8_lossy(&buf).into_owned()
|
||||
});
|
||||
|
@ -43,8 +43,23 @@ pub enum PassWhere {
|
||||
AfterTerminator(BasicBlock),
|
||||
}
|
||||
|
||||
/// If the session is properly configured, dumps a human-readable
|
||||
/// representation of the mir into:
|
||||
/// Cosmetic options for pretty-printing the MIR contents, gathered from the CLI. Each pass can
|
||||
/// override these when dumping its own specific MIR information with [`dump_mir_with_options`].
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct PrettyPrintMirOptions {
|
||||
/// Whether to include extra comments, like span info. From `-Z mir-include-spans`.
|
||||
pub include_extra_comments: bool,
|
||||
}
|
||||
|
||||
impl PrettyPrintMirOptions {
|
||||
/// Create the default set of MIR pretty-printing options from the CLI flags.
|
||||
pub fn from_cli(tcx: TyCtxt<'_>) -> Self {
|
||||
Self { include_extra_comments: tcx.sess.opts.unstable_opts.mir_include_spans }
|
||||
}
|
||||
}
|
||||
|
||||
/// If the session is properly configured, dumps a human-readable representation of the MIR (with
|
||||
/// default pretty-printing options) into:
|
||||
///
|
||||
/// ```text
|
||||
/// rustc.node<node_id>.<pass_num>.<pass_name>.<disambiguator>
|
||||
@ -77,12 +92,40 @@ pub fn dump_mir<'tcx, F>(
|
||||
extra_data: F,
|
||||
) where
|
||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||
{
|
||||
dump_mir_with_options(
|
||||
tcx,
|
||||
pass_num,
|
||||
pass_name,
|
||||
disambiguator,
|
||||
body,
|
||||
extra_data,
|
||||
PrettyPrintMirOptions::from_cli(tcx),
|
||||
);
|
||||
}
|
||||
|
||||
/// If the session is properly configured, dumps a human-readable representation of the MIR, with
|
||||
/// the given [pretty-printing options][PrettyPrintMirOptions].
|
||||
///
|
||||
/// See [`dump_mir`] for more details.
|
||||
///
|
||||
#[inline]
|
||||
pub fn dump_mir_with_options<'tcx, F>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
pass_num: bool,
|
||||
pass_name: &str,
|
||||
disambiguator: &dyn Display,
|
||||
body: &Body<'tcx>,
|
||||
extra_data: F,
|
||||
options: PrettyPrintMirOptions,
|
||||
) where
|
||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||
{
|
||||
if !dump_enabled(tcx, pass_name, body.source.def_id()) {
|
||||
return;
|
||||
}
|
||||
|
||||
dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data);
|
||||
dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data, options);
|
||||
}
|
||||
|
||||
pub fn dump_enabled(tcx: TyCtxt<'_>, pass_name: &str, def_id: DefId) -> bool {
|
||||
@ -112,6 +155,7 @@ fn dump_matched_mir_node<'tcx, F>(
|
||||
disambiguator: &dyn Display,
|
||||
body: &Body<'tcx>,
|
||||
mut extra_data: F,
|
||||
options: PrettyPrintMirOptions,
|
||||
) where
|
||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||
{
|
||||
@ -133,7 +177,7 @@ fn dump_matched_mir_node<'tcx, F>(
|
||||
writeln!(file)?;
|
||||
extra_data(PassWhere::BeforeCFG, &mut file)?;
|
||||
write_user_type_annotations(tcx, body, &mut file)?;
|
||||
write_mir_fn(tcx, body, &mut extra_data, &mut file)?;
|
||||
write_mir_fn(tcx, body, &mut extra_data, &mut file, options)?;
|
||||
extra_data(PassWhere::AfterCFG, &mut file)?;
|
||||
};
|
||||
|
||||
@ -243,12 +287,15 @@ pub fn create_dump_file<'tcx>(
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Whole MIR bodies
|
||||
|
||||
/// Write out a human-readable textual representation for the given MIR.
|
||||
/// Write out a human-readable textual representation for the given MIR, with the default
|
||||
/// [PrettyPrintMirOptions].
|
||||
pub fn write_mir_pretty<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
single: Option<DefId>,
|
||||
w: &mut dyn io::Write,
|
||||
) -> io::Result<()> {
|
||||
let options = PrettyPrintMirOptions::from_cli(tcx);
|
||||
|
||||
writeln!(w, "// WARNING: This output format is intended for human consumers only")?;
|
||||
writeln!(w, "// and is subject to change without notice. Knock yourself out.")?;
|
||||
|
||||
@ -262,11 +309,11 @@ pub fn write_mir_pretty<'tcx>(
|
||||
}
|
||||
|
||||
let render_body = |w: &mut dyn io::Write, body| -> io::Result<()> {
|
||||
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w)?;
|
||||
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w, options)?;
|
||||
|
||||
for body in tcx.promoted_mir(def_id) {
|
||||
writeln!(w)?;
|
||||
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w)?;
|
||||
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w, options)?;
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
@ -278,7 +325,7 @@ pub fn write_mir_pretty<'tcx>(
|
||||
writeln!(w, "// MIR FOR CTFE")?;
|
||||
// Do not use `render_body`, as that would render the promoteds again, but these
|
||||
// are shared between mir_for_ctfe and optimized_mir
|
||||
write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?;
|
||||
write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w, options)?;
|
||||
} else {
|
||||
let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id));
|
||||
render_body(w, instance_mir)?;
|
||||
@ -293,14 +340,15 @@ pub fn write_mir_fn<'tcx, F>(
|
||||
body: &Body<'tcx>,
|
||||
extra_data: &mut F,
|
||||
w: &mut dyn io::Write,
|
||||
options: PrettyPrintMirOptions,
|
||||
) -> io::Result<()>
|
||||
where
|
||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||
{
|
||||
write_mir_intro(tcx, body, w)?;
|
||||
write_mir_intro(tcx, body, w, options)?;
|
||||
for block in body.basic_blocks.indices() {
|
||||
extra_data(PassWhere::BeforeBlock(block), w)?;
|
||||
write_basic_block(tcx, block, body, extra_data, w)?;
|
||||
write_basic_block(tcx, block, body, extra_data, w, options)?;
|
||||
if block.index() + 1 != body.basic_blocks.len() {
|
||||
writeln!(w)?;
|
||||
}
|
||||
@ -321,6 +369,7 @@ fn write_scope_tree(
|
||||
w: &mut dyn io::Write,
|
||||
parent: SourceScope,
|
||||
depth: usize,
|
||||
options: PrettyPrintMirOptions,
|
||||
) -> io::Result<()> {
|
||||
let indent = depth * INDENT.len();
|
||||
|
||||
@ -333,7 +382,7 @@ fn write_scope_tree(
|
||||
|
||||
let indented_debug_info = format!("{0:1$}debug {2:?};", INDENT, indent, var_debug_info);
|
||||
|
||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
||||
if options.include_extra_comments {
|
||||
writeln!(
|
||||
w,
|
||||
"{0:1$} // in {2}",
|
||||
@ -373,7 +422,7 @@ fn write_scope_tree(
|
||||
|
||||
let local_name = if local == RETURN_PLACE { " return place" } else { "" };
|
||||
|
||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
||||
if options.include_extra_comments {
|
||||
writeln!(
|
||||
w,
|
||||
"{0:1$} //{2} in {3}",
|
||||
@ -410,7 +459,7 @@ fn write_scope_tree(
|
||||
|
||||
let indented_header = format!("{0:1$}scope {2}{3} {{", "", indent, child.index(), special);
|
||||
|
||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
||||
if options.include_extra_comments {
|
||||
if let Some(span) = span {
|
||||
writeln!(
|
||||
w,
|
||||
@ -426,7 +475,7 @@ fn write_scope_tree(
|
||||
writeln!(w, "{indented_header}")?;
|
||||
}
|
||||
|
||||
write_scope_tree(tcx, body, scope_tree, w, child, depth + 1)?;
|
||||
write_scope_tree(tcx, body, scope_tree, w, child, depth + 1, options)?;
|
||||
writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?;
|
||||
}
|
||||
|
||||
@ -449,10 +498,11 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
||||
|
||||
/// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
|
||||
/// local variables (both user-defined bindings and compiler temporaries).
|
||||
pub fn write_mir_intro<'tcx>(
|
||||
fn write_mir_intro<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'_>,
|
||||
w: &mut dyn io::Write,
|
||||
options: PrettyPrintMirOptions,
|
||||
) -> io::Result<()> {
|
||||
write_mir_sig(tcx, body, w)?;
|
||||
writeln!(w, "{{")?;
|
||||
@ -468,7 +518,7 @@ pub fn write_mir_intro<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1)?;
|
||||
write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1, options)?;
|
||||
|
||||
// Add an empty line before the first block is printed.
|
||||
writeln!(w)?;
|
||||
@ -651,12 +701,13 @@ pub fn dump_mir_def_ids(tcx: TyCtxt<'_>, single: Option<DefId>) -> Vec<DefId> {
|
||||
// Basic blocks and their parts (statements, terminators, ...)
|
||||
|
||||
/// Write out a human-readable textual representation for the given basic block.
|
||||
pub fn write_basic_block<'tcx, F>(
|
||||
fn write_basic_block<'tcx, F>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
block: BasicBlock,
|
||||
body: &Body<'tcx>,
|
||||
extra_data: &mut F,
|
||||
w: &mut dyn io::Write,
|
||||
options: PrettyPrintMirOptions,
|
||||
) -> io::Result<()>
|
||||
where
|
||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||
@ -672,7 +723,7 @@ pub fn write_basic_block<'tcx, F>(
|
||||
for statement in &data.statements {
|
||||
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
||||
let indented_body = format!("{INDENT}{INDENT}{statement:?};");
|
||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
||||
if options.include_extra_comments {
|
||||
writeln!(
|
||||
w,
|
||||
"{:A$} // {}{}",
|
||||
@ -689,9 +740,14 @@ pub fn write_basic_block<'tcx, F>(
|
||||
writeln!(w, "{indented_body}")?;
|
||||
}
|
||||
|
||||
write_extra(tcx, w, |visitor| {
|
||||
write_extra(
|
||||
tcx,
|
||||
w,
|
||||
|visitor| {
|
||||
visitor.visit_statement(statement, current_location);
|
||||
})?;
|
||||
},
|
||||
options,
|
||||
)?;
|
||||
|
||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||
|
||||
@ -701,7 +757,7 @@ pub fn write_basic_block<'tcx, F>(
|
||||
// Terminator at the bottom.
|
||||
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
||||
let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
|
||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
||||
if options.include_extra_comments {
|
||||
writeln!(
|
||||
w,
|
||||
"{:A$} // {}{}",
|
||||
@ -718,9 +774,14 @@ pub fn write_basic_block<'tcx, F>(
|
||||
writeln!(w, "{indented_terminator}")?;
|
||||
}
|
||||
|
||||
write_extra(tcx, w, |visitor| {
|
||||
write_extra(
|
||||
tcx,
|
||||
w,
|
||||
|visitor| {
|
||||
visitor.visit_terminator(data.terminator(), current_location);
|
||||
})?;
|
||||
},
|
||||
options,
|
||||
)?;
|
||||
|
||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||
extra_data(PassWhere::AfterTerminator(block), w)?;
|
||||
@ -1271,11 +1332,12 @@ fn write_extra<'tcx, F>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
write: &mut dyn io::Write,
|
||||
mut visit_op: F,
|
||||
options: PrettyPrintMirOptions,
|
||||
) -> io::Result<()>
|
||||
where
|
||||
F: FnMut(&mut ExtraComments<'tcx>),
|
||||
{
|
||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
||||
if options.include_extra_comments {
|
||||
let mut extra_comments = ExtraComments { tcx, comments: vec![] };
|
||||
visit_op(&mut extra_comments);
|
||||
for comment in extra_comments.comments {
|
||||
@ -1890,7 +1952,7 @@ pub(crate) fn pretty_print_const_value<'tcx>(
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Miscellaneous
|
||||
|
||||
/// Calc converted u64 decimal into hex and return it's length in chars
|
||||
/// Calc converted u64 decimal into hex and return its length in chars.
|
||||
///
|
||||
/// ```ignore (cannot-test-private-function)
|
||||
/// assert_eq!(1, hex_number_length(0));
|
||||
|
Loading…
Reference in New Issue
Block a user