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::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::visit::Visitor;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::ty::item_path;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
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<()>,
|
||||
{
|
||||
let _: io::Result<()> = do catch {
|
||||
let mut file = create_dump_file(
|
||||
tcx,
|
||||
"mir",
|
||||
pass_num,
|
||||
pass_name,
|
||||
disambiguator,
|
||||
source,
|
||||
)?;
|
||||
let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?;
|
||||
writeln!(file, "// MIR for `{}`", node_path)?;
|
||||
writeln!(file, "// source = {:?}", source)?;
|
||||
writeln!(file, "// pass_name = {}", pass_name)?;
|
||||
@ -149,14 +143,8 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
||||
|
||||
if tcx.sess.opts.debugging_opts.dump_mir_graphviz {
|
||||
let _: io::Result<()> = do catch {
|
||||
let mut file = create_dump_file(
|
||||
tcx,
|
||||
"dot",
|
||||
pass_num,
|
||||
pass_name,
|
||||
disambiguator,
|
||||
source,
|
||||
)?;
|
||||
let mut file =
|
||||
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
|
||||
write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
|
||||
Ok(())
|
||||
};
|
||||
@ -297,10 +285,10 @@ where
|
||||
}
|
||||
|
||||
/// Write out a human-readable textual representation for the given basic block.
|
||||
pub fn write_basic_block<F>(
|
||||
tcx: TyCtxt,
|
||||
pub fn write_basic_block<'cx, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
block: BasicBlock,
|
||||
mir: &Mir,
|
||||
mir: &Mir<'tcx>,
|
||||
extra_data: &mut F,
|
||||
w: &mut Write,
|
||||
) -> io::Result<()>
|
||||
@ -330,6 +318,11 @@ where
|
||||
comment(tcx, statement.source_info),
|
||||
A = ALIGN,
|
||||
)?;
|
||||
|
||||
write_extra(tcx, w, |visitor| {
|
||||
visitor.visit_statement(current_location.block, statement, current_location);
|
||||
})?;
|
||||
|
||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||
|
||||
current_location.statement_index += 1;
|
||||
@ -346,11 +339,93 @@ where
|
||||
comment(tcx, data.terminator().source_info),
|
||||
A = ALIGN,
|
||||
)?;
|
||||
|
||||
write_extra(tcx, w, |visitor| {
|
||||
visitor.visit_terminator(current_location.block, data.terminator(), current_location);
|
||||
})?;
|
||||
|
||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||
|
||||
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 {
|
||||
format!(
|
||||
"scope {} at {}",
|
||||
|
@ -2535,7 +2535,10 @@ impl<'test> TestCx<'test> {
|
||||
let mut dumped_file = fs::File::open(output_file.clone()).unwrap();
|
||||
let mut dumped_string = String::new();
|
||||
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
|
||||
.iter()
|
||||
.filter(|&l| {
|
||||
@ -2573,7 +2576,7 @@ impl<'test> TestCx<'test> {
|
||||
.join("\n");
|
||||
panic!(
|
||||
"Did not find expected line, error: {}\n\
|
||||
Actual Line: {:?}\n\
|
||||
Expected Line: {:?}\n\
|
||||
Expected:\n{}\n\
|
||||
Actual:\n{}",
|
||||
extra_msg,
|
||||
@ -2599,7 +2602,9 @@ impl<'test> TestCx<'test> {
|
||||
error(
|
||||
expected_line,
|
||||
format!(
|
||||
"Mismatch in lines\nCurrnt block: {}\nExpected Line: {:?}",
|
||||
"Mismatch in lines\n\
|
||||
Current block: {}\n\
|
||||
Actual Line: {:?}",
|
||||
start_block_line.unwrap_or("None"),
|
||||
dumped_line
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user