]> git.lizzy.rs Git - rust.git/commitdiff
extend MIR dump with detailed, extra information
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 22 Nov 2017 22:33:26 +0000 (17:33 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 7 Dec 2017 10:27:58 +0000 (05:27 -0500)
src/librustc_mir/util/pretty.rs
src/tools/compiletest/src/runtest.rs

index 8a3db0eb25b99b0d921ff4b907b6add7f3cb6b17..98d746952a402391de5ac3d68256db1de3cf76dc 100644 (file)
@@ -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)?;
@@ -148,15 +142,9 @@ 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 _: io::Result<()> = do catch {
+            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 @@ pub fn write_mir_fn<'a, 'gcx, 'tcx, F>(
 }
 
 /// 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 @@ pub fn write_basic_block<F>(
             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 @@ pub fn write_basic_block<F>(
         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 {}",
index 91d51d359ecec08b2a44e82d0de93a0051a7edf9..a18f4ec1aadb469b83e6762d447699ed9eb04098 100644 (file)
@@ -2535,7 +2535,10 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &[ExpectedL
         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 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &[ExpectedL
                 .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 @@ fn compare_mir_test_output(&self, test_name: &str, expected_content: &[ExpectedL
                         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
                             ),