@@ -21,6 +21,8 @@ use syntax::ast::NodeId;
2121use syntax:: codemap:: Span ;
2222
2323const INDENT : & ' static str = " " ;
24+ /// Alignment for lining up comments following MIR statements
25+ const ALIGN : usize = 40 ;
2426
2527/// If the session is properly configured, dumps a human-readable
2628/// representation of the mir into:
@@ -79,11 +81,20 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
7981 -> io:: Result < ( ) >
8082 where I : Iterator < Item =( & ' a NodeId , & ' a Mir < ' tcx > ) > , ' tcx : ' a
8183{
84+ let mut first = true ;
8285 for ( & id, mir) in iter {
86+ if first {
87+ first = false ;
88+ } else {
89+ // Put empty lines between all items
90+ writeln ! ( w, "" ) ?;
91+ }
92+
8393 let src = MirSource :: from_node ( tcx, id) ;
8494 write_mir_fn ( tcx, src, mir, w, None ) ?;
8595
8696 for ( i, mir) in mir. promoted . iter ( ) . enumerate ( ) {
97+ writeln ! ( w, "" ) ?;
8798 write_mir_fn ( tcx, MirSource :: Promoted ( id, i) , mir, w, None ) ?;
8899 }
89100 }
@@ -131,7 +142,10 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
131142 . or_insert ( vec ! [ ] )
132143 . push ( ScopeId :: new ( index) ) ;
133144 }
134- write_scope_tree ( tcx, mir, auxiliary, & scope_tree, w, None , 1 ) ?;
145+
146+ writeln ! ( w, "{}scope tree:" , INDENT ) ?;
147+ write_scope_tree ( tcx, mir, auxiliary, & scope_tree, w, None , 1 , false ) ?;
148+ writeln ! ( w, "" ) ?;
135149
136150 writeln ! ( w, "}}" ) ?;
137151 Ok ( ( ) )
@@ -147,7 +161,7 @@ fn write_basic_block(tcx: TyCtxt,
147161 let data = mir. basic_block_data ( block) ;
148162
149163 // Basic block label at the top.
150- writeln ! ( w, "\n {}{:?}: {{" , INDENT , block) ?;
164+ writeln ! ( w, "{}{:?}: {{" , INDENT , block) ?;
151165
152166 // List of statements in the middle.
153167 let mut current_location = Location { block : block, statement_index : 0 } ;
@@ -165,25 +179,27 @@ fn write_basic_block(tcx: TyCtxt,
165179 }
166180 }
167181
168- writeln ! ( w, "{0}{0}{1:?}; // {2}" ,
169- INDENT ,
170- statement,
182+ let indented_mir = format ! ( "{0}{0}{1:?};" , INDENT , statement) ;
183+ writeln ! ( w, "{0:1$} // {2}" ,
184+ indented_mir,
185+ ALIGN ,
171186 comment( tcx, statement. scope, statement. span) ) ?;
172187
173188 current_location. statement_index += 1 ;
174189 }
175190
176191 // Terminator at the bottom.
177- writeln ! ( w, "{0}{0}{1:?}; // {2}" ,
178- INDENT ,
179- data. terminator( ) . kind,
192+ let indented_terminator = format ! ( "{0}{0}{1:?};" , INDENT , data. terminator( ) . kind) ;
193+ writeln ! ( w, "{0:1$} // {2}" ,
194+ indented_terminator,
195+ ALIGN ,
180196 comment( tcx, data. terminator( ) . scope, data. terminator( ) . span) ) ?;
181197
182- writeln ! ( w, "{}}}" , INDENT )
198+ writeln ! ( w, "{}}}\n " , INDENT )
183199}
184200
185201fn comment ( tcx : TyCtxt , scope : ScopeId , span : Span ) -> String {
186- format ! ( "Scope({}) at {}" , scope. index( ) , tcx. sess. codemap( ) . span_to_string( span) )
202+ format ! ( "scope {} at {}" , scope. index( ) , tcx. sess. codemap( ) . span_to_string( span) )
187203}
188204
189205fn write_scope_tree ( tcx : TyCtxt ,
@@ -192,28 +208,58 @@ fn write_scope_tree(tcx: TyCtxt,
192208 scope_tree : & FnvHashMap < Option < ScopeId > , Vec < ScopeId > > ,
193209 w : & mut Write ,
194210 parent : Option < ScopeId > ,
195- depth : usize )
211+ depth : usize ,
212+ same_line : bool )
196213 -> io:: Result < ( ) > {
197- for & child in scope_tree. get ( & parent) . unwrap_or ( & vec ! [ ] ) {
198- let indent = depth * INDENT . len ( ) ;
214+ let indent = if same_line {
215+ 0
216+ } else {
217+ depth * INDENT . len ( )
218+ } ;
219+
220+ let children = match scope_tree. get ( & parent) {
221+ Some ( childs) => childs,
222+ None => return Ok ( ( ) ) ,
223+ } ;
224+
225+ for ( index, & child) in children. iter ( ) . enumerate ( ) {
226+ if index == 0 && same_line {
227+ // We know we're going to output a scope, so prefix it with a space to separate it from
228+ // the previous scopes on this line
229+ write ! ( w, " " ) ?;
230+ }
231+
199232 let data = & mir. scopes [ child] ;
200233 assert_eq ! ( data. parent_scope, parent) ;
201- writeln ! ( w, "{0:1$}Scope( {2}) {{ " , "" , indent, child. index( ) ) ?;
234+ write ! ( w, "{0:1$}{2}" , "" , indent, child. index( ) ) ?;
202235
203236 let indent = indent + INDENT . len ( ) ;
204- if let Some ( parent) = parent {
205- writeln ! ( w, "{0:1$}Parent: Scope({2})" , "" , indent, parent. index( ) ) ?;
206- }
207237
208238 if let Some ( auxiliary) = auxiliary {
209239 let extent = auxiliary[ child] . extent ;
210240 let data = tcx. region_maps . code_extent_data ( extent) ;
211241 writeln ! ( w, "{0:1$}Extent: {2:?}" , "" , indent, data) ?;
212242 }
213243
214- write_scope_tree ( tcx, mir, auxiliary, scope_tree, w,
215- Some ( child) , depth + 1 ) ?;
244+ let child_count = scope_tree. get ( & Some ( child) ) . map ( Vec :: len) . unwrap_or ( 0 ) ;
245+ if child_count < 2 {
246+ // Skip the braces when there's no or only a single subscope
247+ write_scope_tree ( tcx, mir, auxiliary, scope_tree, w,
248+ Some ( child) , depth, true ) ?;
249+ } else {
250+ // 2 or more child scopes? Put them in braces and on new lines.
251+ writeln ! ( w, " {{" ) ?;
252+ write_scope_tree ( tcx, mir, auxiliary, scope_tree, w,
253+ Some ( child) , depth + 1 , false ) ?;
254+
255+ write ! ( w, "\n {0:1$}}}" , "" , depth * INDENT . len( ) ) ?;
256+ }
257+
258+ if !same_line && index + 1 < children. len ( ) {
259+ writeln ! ( w, "" ) ?;
260+ }
216261 }
262+
217263 Ok ( ( ) )
218264}
219265
@@ -261,13 +307,20 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
261307
262308 // User variable types (including the user's name in a comment).
263309 for ( i, var) in mir. var_decls . iter ( ) . enumerate ( ) {
264- write ! ( w, "{}let " , INDENT ) ?;
265- if var. mutability == Mutability :: Mut {
266- write ! ( w, "mut " ) ?;
267- }
268- writeln ! ( w, "{:?}: {}; // {} in {}" ,
269- Lvalue :: Var ( i as u32 ) ,
270- var. ty,
310+ let mut_str = if var. mutability == Mutability :: Mut {
311+ "mut "
312+ } else {
313+ ""
314+ } ;
315+
316+ let indented_var = format ! ( "{}let {}{:?}: {};" ,
317+ INDENT ,
318+ mut_str,
319+ Lvalue :: Var ( i as u32 ) ,
320+ var. ty) ;
321+ writeln ! ( w, "{0:1$} // \" {2}\" in {3}" ,
322+ indented_var,
323+ ALIGN ,
271324 var. name,
272325 comment( tcx, var. scope, var. span) ) ?;
273326 }
@@ -277,5 +330,10 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
277330 writeln ! ( w, "{}let mut {:?}: {};" , INDENT , Lvalue :: Temp ( i as u32 ) , temp. ty) ?;
278331 }
279332
333+ // Wrote any declaration? Add an empty line before the first block is printed.
334+ if !mir. var_decls . is_empty ( ) || !mir. temp_decls . is_empty ( ) {
335+ writeln ! ( w, "" ) ?;
336+ }
337+
280338 Ok ( ( ) )
281339}
0 commit comments