@@ -21,6 +21,8 @@ use syntax::ast::NodeId;
21
21
use syntax:: codemap:: Span ;
22
22
23
23
const INDENT : & ' static str = " " ;
24
+ /// Alignment for lining up comments following MIR statements
25
+ const ALIGN : usize = 40 ;
24
26
25
27
/// If the session is properly configured, dumps a human-readable
26
28
/// representation of the mir into:
@@ -79,11 +81,20 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
79
81
-> io:: Result < ( ) >
80
82
where I : Iterator < Item =( & ' a NodeId , & ' a Mir < ' tcx > ) > , ' tcx : ' a
81
83
{
84
+ let mut first = true ;
82
85
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
+
83
93
let src = MirSource :: from_node ( tcx, id) ;
84
94
write_mir_fn ( tcx, src, mir, w, None ) ?;
85
95
86
96
for ( i, mir) in mir. promoted . iter ( ) . enumerate ( ) {
97
+ writeln ! ( w, "" ) ?;
87
98
write_mir_fn ( tcx, MirSource :: Promoted ( id, i) , mir, w, None ) ?;
88
99
}
89
100
}
@@ -131,7 +142,10 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
131
142
. or_insert ( vec ! [ ] )
132
143
. push ( ScopeId :: new ( index) ) ;
133
144
}
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, "" ) ?;
135
149
136
150
writeln ! ( w, "}}" ) ?;
137
151
Ok ( ( ) )
@@ -147,7 +161,7 @@ fn write_basic_block(tcx: TyCtxt,
147
161
let data = mir. basic_block_data ( block) ;
148
162
149
163
// Basic block label at the top.
150
- writeln ! ( w, "\n {}{:?}: {{" , INDENT , block) ?;
164
+ writeln ! ( w, "{}{:?}: {{" , INDENT , block) ?;
151
165
152
166
// List of statements in the middle.
153
167
let mut current_location = Location { block : block, statement_index : 0 } ;
@@ -165,25 +179,27 @@ fn write_basic_block(tcx: TyCtxt,
165
179
}
166
180
}
167
181
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 ,
171
186
comment( tcx, statement. scope, statement. span) ) ?;
172
187
173
188
current_location. statement_index += 1 ;
174
189
}
175
190
176
191
// 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 ,
180
196
comment( tcx, data. terminator( ) . scope, data. terminator( ) . span) ) ?;
181
197
182
- writeln ! ( w, "{}}}" , INDENT )
198
+ writeln ! ( w, "{}}}\n " , INDENT )
183
199
}
184
200
185
201
fn 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) )
187
203
}
188
204
189
205
fn write_scope_tree ( tcx : TyCtxt ,
@@ -192,28 +208,58 @@ fn write_scope_tree(tcx: TyCtxt,
192
208
scope_tree : & FnvHashMap < Option < ScopeId > , Vec < ScopeId > > ,
193
209
w : & mut Write ,
194
210
parent : Option < ScopeId > ,
195
- depth : usize )
211
+ depth : usize ,
212
+ same_line : bool )
196
213
-> 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
+
199
232
let data = & mir. scopes [ child] ;
200
233
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( ) ) ?;
202
235
203
236
let indent = indent + INDENT . len ( ) ;
204
- if let Some ( parent) = parent {
205
- writeln ! ( w, "{0:1$}Parent: Scope({2})" , "" , indent, parent. index( ) ) ?;
206
- }
207
237
208
238
if let Some ( auxiliary) = auxiliary {
209
239
let extent = auxiliary[ child] . extent ;
210
240
let data = tcx. region_maps . code_extent_data ( extent) ;
211
241
writeln ! ( w, "{0:1$}Extent: {2:?}" , "" , indent, data) ?;
212
242
}
213
243
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
+ }
216
261
}
262
+
217
263
Ok ( ( ) )
218
264
}
219
265
@@ -261,13 +307,20 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
261
307
262
308
// User variable types (including the user's name in a comment).
263
309
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 ,
271
324
var. name,
272
325
comment( tcx, var. scope, var. span) ) ?;
273
326
}
@@ -277,5 +330,10 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
277
330
writeln ! ( w, "{}let mut {:?}: {};" , INDENT , Lvalue :: Temp ( i as u32 ) , temp. ty) ?;
278
331
}
279
332
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
+
280
338
Ok ( ( ) )
281
339
}
0 commit comments