diff options
| author | bors <bors@rust-lang.org> | 2016-05-15 01:14:10 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-05-15 01:14:10 -0700 |
| commit | 1a26d2364f9da1667ca0098d3cc4a213d131f481 (patch) | |
| tree | 2b3314160aaced7d8bc0c7bbb7ed34cd3016e1dc | |
| parent | 088d4178522d4e9464c6beac70b14724670ee735 (diff) | |
| parent | 2c7e398935fe10aa2adea453ca0a2251b3c387e8 (diff) | |
Auto merge of #33607 - jonas-schievink:prettier-mir, r=eddyb
Some simple improvements to MIR pretty printing In short, this PR changes the MIR printer so that it: * places an empty line between the MIR for each item * does *not* write an empty line before the first BB when there are no var decls * aligns the "// Scope" comments 50 chars in (makes the output more readable) * prints the scope comments as "// scope N at ..." instead of "// Scope(N) at ..." * prints a prettier scope tree: * no more unbalanced delimiters! * no more "Parent" entry (these convey no useful information) * drop the "Scope()" and just print scope IDs * no braces when the scope is empty In action: https://gist.github.com/jonas-schievink/1c11226cbb112892a9470ce0f9870b65
| -rw-r--r-- | src/librustc_mir/pretty.rs | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index bf6689de236..fb29cbd5fa8 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -21,6 +21,8 @@ use syntax::ast::NodeId; use syntax::codemap::Span; const INDENT: &'static str = " "; +/// Alignment for lining up comments following MIR statements +const ALIGN: usize = 40; /// If the session is properly configured, dumps a human-readable /// representation of the mir into: @@ -79,11 +81,20 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>, -> io::Result<()> where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a { + let mut first = true; for (&id, mir) in iter { + if first { + first = false; + } else { + // Put empty lines between all items + writeln!(w, "")?; + } + let src = MirSource::from_node(tcx, id); write_mir_fn(tcx, src, mir, w, None)?; for (i, mir) in mir.promoted.iter().enumerate() { + writeln!(w, "")?; write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w, None)?; } } @@ -131,7 +142,10 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .or_insert(vec![]) .push(ScopeId::new(index)); } - write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1)?; + + writeln!(w, "{}scope tree:", INDENT)?; + write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1, false)?; + writeln!(w, "")?; writeln!(w, "}}")?; Ok(()) @@ -147,7 +161,7 @@ fn write_basic_block(tcx: TyCtxt, let data = mir.basic_block_data(block); // Basic block label at the top. - writeln!(w, "\n{}{:?}: {{", INDENT, block)?; + writeln!(w, "{}{:?}: {{", INDENT, block)?; // List of statements in the middle. let mut current_location = Location { block: block, statement_index: 0 }; @@ -165,25 +179,27 @@ fn write_basic_block(tcx: TyCtxt, } } - writeln!(w, "{0}{0}{1:?}; // {2}", - INDENT, - statement, + let indented_mir = format!("{0}{0}{1:?};", INDENT, statement); + writeln!(w, "{0:1$} // {2}", + indented_mir, + ALIGN, comment(tcx, statement.scope, statement.span))?; current_location.statement_index += 1; } // Terminator at the bottom. - writeln!(w, "{0}{0}{1:?}; // {2}", - INDENT, - data.terminator().kind, + let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); + writeln!(w, "{0:1$} // {2}", + indented_terminator, + ALIGN, comment(tcx, data.terminator().scope, data.terminator().span))?; - writeln!(w, "{}}}", INDENT) + writeln!(w, "{}}}\n", INDENT) } fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String { - format!("Scope({}) at {}", scope.index(), tcx.sess.codemap().span_to_string(span)) + format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span)) } fn write_scope_tree(tcx: TyCtxt, @@ -192,18 +208,32 @@ fn write_scope_tree(tcx: TyCtxt, scope_tree: &FnvHashMap<Option<ScopeId>, Vec<ScopeId>>, w: &mut Write, parent: Option<ScopeId>, - depth: usize) + depth: usize, + same_line: bool) -> io::Result<()> { - for &child in scope_tree.get(&parent).unwrap_or(&vec![]) { - let indent = depth * INDENT.len(); + let indent = if same_line { + 0 + } else { + depth * INDENT.len() + }; + + let children = match scope_tree.get(&parent) { + Some(childs) => childs, + None => return Ok(()), + }; + + for (index, &child) in children.iter().enumerate() { + if index == 0 && same_line { + // We know we're going to output a scope, so prefix it with a space to separate it from + // the previous scopes on this line + write!(w, " ")?; + } + let data = &mir.scopes[child]; assert_eq!(data.parent_scope, parent); - writeln!(w, "{0:1$}Scope({2}) {{", "", indent, child.index())?; + write!(w, "{0:1$}{2}", "", indent, child.index())?; let indent = indent + INDENT.len(); - if let Some(parent) = parent { - writeln!(w, "{0:1$}Parent: Scope({2})", "", indent, parent.index())?; - } if let Some(auxiliary) = auxiliary { let extent = auxiliary[child].extent; @@ -211,9 +241,25 @@ fn write_scope_tree(tcx: TyCtxt, writeln!(w, "{0:1$}Extent: {2:?}", "", indent, data)?; } - write_scope_tree(tcx, mir, auxiliary, scope_tree, w, - Some(child), depth + 1)?; + let child_count = scope_tree.get(&Some(child)).map(Vec::len).unwrap_or(0); + if child_count < 2 { + // Skip the braces when there's no or only a single subscope + write_scope_tree(tcx, mir, auxiliary, scope_tree, w, + Some(child), depth, true)?; + } else { + // 2 or more child scopes? Put them in braces and on new lines. + writeln!(w, " {{")?; + write_scope_tree(tcx, mir, auxiliary, scope_tree, w, + Some(child), depth + 1, false)?; + + write!(w, "\n{0:1$}}}", "", depth * INDENT.len())?; + } + + if !same_line && index + 1 < children.len() { + writeln!(w, "")?; + } } + Ok(()) } @@ -261,13 +307,20 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // User variable types (including the user's name in a comment). for (i, var) in mir.var_decls.iter().enumerate() { - write!(w, "{}let ", INDENT)?; - if var.mutability == Mutability::Mut { - write!(w, "mut ")?; - } - writeln!(w, "{:?}: {}; // {} in {}", - Lvalue::Var(i as u32), - var.ty, + let mut_str = if var.mutability == Mutability::Mut { + "mut " + } else { + "" + }; + + let indented_var = format!("{}let {}{:?}: {};", + INDENT, + mut_str, + Lvalue::Var(i as u32), + var.ty); + writeln!(w, "{0:1$} // \"{2}\" in {3}", + indented_var, + ALIGN, var.name, comment(tcx, var.scope, var.span))?; } @@ -277,5 +330,10 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, writeln!(w, "{}let mut {:?}: {};", INDENT, Lvalue::Temp(i as u32), temp.ty)?; } + // Wrote any declaration? Add an empty line before the first block is printed. + if !mir.var_decls.is_empty() || !mir.temp_decls.is_empty() { + writeln!(w, "")?; + } + Ok(()) } |
