extend MIR dump with detailed, extra information
This commit is contained in:
parent
e5dc4ba280
commit
2ec959fc35
@ -11,7 +11,8 @@
|
|||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::mir::visit::Visitor;
|
||||||
|
use rustc::ty::{self, TyCtxt};
|
||||||
use rustc::ty::item_path;
|
use rustc::ty::item_path;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
@ -125,14 +126,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
|||||||
F: FnMut(PassWhere, &mut Write) -> io::Result<()>,
|
F: FnMut(PassWhere, &mut Write) -> io::Result<()>,
|
||||||
{
|
{
|
||||||
let _: io::Result<()> = do catch {
|
let _: io::Result<()> = do catch {
|
||||||
let mut file = create_dump_file(
|
let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?;
|
||||||
tcx,
|
|
||||||
"mir",
|
|
||||||
pass_num,
|
|
||||||
pass_name,
|
|
||||||
disambiguator,
|
|
||||||
source,
|
|
||||||
)?;
|
|
||||||
writeln!(file, "// MIR for `{}`", node_path)?;
|
writeln!(file, "// MIR for `{}`", node_path)?;
|
||||||
writeln!(file, "// source = {:?}", source)?;
|
writeln!(file, "// source = {:?}", source)?;
|
||||||
writeln!(file, "// pass_name = {}", pass_name)?;
|
writeln!(file, "// pass_name = {}", pass_name)?;
|
||||||
@ -148,15 +142,9 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if tcx.sess.opts.debugging_opts.dump_mir_graphviz {
|
if tcx.sess.opts.debugging_opts.dump_mir_graphviz {
|
||||||
let _: io::Result<()> = do catch {
|
let _: io::Result<()> = do catch {
|
||||||
let mut file = create_dump_file(
|
let mut file =
|
||||||
tcx,
|
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
|
||||||
"dot",
|
|
||||||
pass_num,
|
|
||||||
pass_name,
|
|
||||||
disambiguator,
|
|
||||||
source,
|
|
||||||
)?;
|
|
||||||
write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
|
write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
@ -297,10 +285,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write out a human-readable textual representation for the given basic block.
|
/// Write out a human-readable textual representation for the given basic block.
|
||||||
pub fn write_basic_block<F>(
|
pub fn write_basic_block<'cx, 'gcx, 'tcx, F>(
|
||||||
tcx: TyCtxt,
|
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
mir: &Mir,
|
mir: &Mir<'tcx>,
|
||||||
extra_data: &mut F,
|
extra_data: &mut F,
|
||||||
w: &mut Write,
|
w: &mut Write,
|
||||||
) -> io::Result<()>
|
) -> io::Result<()>
|
||||||
@ -330,6 +318,11 @@ where
|
|||||||
comment(tcx, statement.source_info),
|
comment(tcx, statement.source_info),
|
||||||
A = ALIGN,
|
A = ALIGN,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
write_extra(tcx, w, |visitor| {
|
||||||
|
visitor.visit_statement(current_location.block, statement, current_location);
|
||||||
|
})?;
|
||||||
|
|
||||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||||
|
|
||||||
current_location.statement_index += 1;
|
current_location.statement_index += 1;
|
||||||
@ -346,11 +339,93 @@ where
|
|||||||
comment(tcx, data.terminator().source_info),
|
comment(tcx, data.terminator().source_info),
|
||||||
A = ALIGN,
|
A = ALIGN,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
write_extra(tcx, w, |visitor| {
|
||||||
|
visitor.visit_terminator(current_location.block, data.terminator(), current_location);
|
||||||
|
})?;
|
||||||
|
|
||||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||||
|
|
||||||
writeln!(w, "{}}}", INDENT)
|
writeln!(w, "{}}}", INDENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// After we print the main statement, we sometimes dump extra
|
||||||
|
/// information. There's often a lot of little things "nuzzled up" in
|
||||||
|
/// a statement.
|
||||||
|
fn write_extra<'cx, 'gcx, 'tcx, F>(
|
||||||
|
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||||
|
write: &mut Write,
|
||||||
|
mut visit_op: F,
|
||||||
|
) -> io::Result<()>
|
||||||
|
where F: FnMut(&mut ExtraComments<'cx, 'gcx, 'tcx>)
|
||||||
|
{
|
||||||
|
let mut extra_comments = ExtraComments {
|
||||||
|
_tcx: tcx,
|
||||||
|
comments: vec![],
|
||||||
|
};
|
||||||
|
visit_op(&mut extra_comments);
|
||||||
|
for comment in extra_comments.comments {
|
||||||
|
writeln!(write, "{:A$} // {}", "", comment, A = ALIGN)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ExtraComments<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||||
|
_tcx: TyCtxt<'cx, 'gcx, 'tcx>, // don't need it now, but bet we will soon
|
||||||
|
comments: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'cx, 'gcx, 'tcx> ExtraComments<'cx, 'gcx, 'tcx> {
|
||||||
|
fn push(&mut self, lines: &str) {
|
||||||
|
for line in lines.split("\n") {
|
||||||
|
self.comments.push(line.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> {
|
||||||
|
fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
|
||||||
|
self.super_constant(constant, location);
|
||||||
|
let Constant { span, ty, literal } = constant;
|
||||||
|
self.push(&format!("mir::Constant"));
|
||||||
|
self.push(&format!("└ span: {:?}", span));
|
||||||
|
self.push(&format!("└ ty: {:?}", ty));
|
||||||
|
self.push(&format!("└ literal: {:?}", literal));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
|
||||||
|
self.super_const(constant);
|
||||||
|
let ty::Const { ty, val } = constant;
|
||||||
|
self.push(&format!("ty::Const"));
|
||||||
|
self.push(&format!("└ ty: {:?}", ty));
|
||||||
|
self.push(&format!("└ val: {:?}", val));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||||
|
self.super_rvalue(rvalue, location);
|
||||||
|
match rvalue {
|
||||||
|
Rvalue::Aggregate(kind, _) => match **kind {
|
||||||
|
AggregateKind::Closure(def_id, substs) => {
|
||||||
|
self.push(&format!("closure"));
|
||||||
|
self.push(&format!("└ def_id: {:?}", def_id));
|
||||||
|
self.push(&format!("└ substs: {:#?}", substs));
|
||||||
|
}
|
||||||
|
|
||||||
|
AggregateKind::Generator(def_id, substs, interior) => {
|
||||||
|
self.push(&format!("generator"));
|
||||||
|
self.push(&format!("└ def_id: {:?}", def_id));
|
||||||
|
self.push(&format!("└ substs: {:#?}", substs));
|
||||||
|
self.push(&format!("└ interior: {:?}", interior));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String {
|
fn comment(tcx: TyCtxt, SourceInfo { span, scope }: SourceInfo) -> String {
|
||||||
format!(
|
format!(
|
||||||
"scope {} at {}",
|
"scope {} at {}",
|
||||||
|
@ -2535,7 +2535,10 @@ impl<'test> TestCx<'test> {
|
|||||||
let mut dumped_file = fs::File::open(output_file.clone()).unwrap();
|
let mut dumped_file = fs::File::open(output_file.clone()).unwrap();
|
||||||
let mut dumped_string = String::new();
|
let mut dumped_string = String::new();
|
||||||
dumped_file.read_to_string(&mut dumped_string).unwrap();
|
dumped_file.read_to_string(&mut dumped_string).unwrap();
|
||||||
let mut dumped_lines = dumped_string.lines().filter(|l| !l.is_empty());
|
let mut dumped_lines = dumped_string
|
||||||
|
.lines()
|
||||||
|
.map(|l| nocomment_mir_line(l))
|
||||||
|
.filter(|l| !l.is_empty());
|
||||||
let mut expected_lines = expected_content
|
let mut expected_lines = expected_content
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&l| {
|
.filter(|&l| {
|
||||||
@ -2573,7 +2576,7 @@ impl<'test> TestCx<'test> {
|
|||||||
.join("\n");
|
.join("\n");
|
||||||
panic!(
|
panic!(
|
||||||
"Did not find expected line, error: {}\n\
|
"Did not find expected line, error: {}\n\
|
||||||
Actual Line: {:?}\n\
|
Expected Line: {:?}\n\
|
||||||
Expected:\n{}\n\
|
Expected:\n{}\n\
|
||||||
Actual:\n{}",
|
Actual:\n{}",
|
||||||
extra_msg,
|
extra_msg,
|
||||||
@ -2599,7 +2602,9 @@ impl<'test> TestCx<'test> {
|
|||||||
error(
|
error(
|
||||||
expected_line,
|
expected_line,
|
||||||
format!(
|
format!(
|
||||||
"Mismatch in lines\nCurrnt block: {}\nExpected Line: {:?}",
|
"Mismatch in lines\n\
|
||||||
|
Current block: {}\n\
|
||||||
|
Actual Line: {:?}",
|
||||||
start_block_line.unwrap_or("None"),
|
start_block_line.unwrap_or("None"),
|
||||||
dumped_line
|
dumped_line
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user