11
11
use rustc:: hir;
12
12
use rustc:: hir:: def_id:: { DefId , LOCAL_CRATE } ;
13
13
use rustc:: mir:: * ;
14
- use rustc:: ty:: TyCtxt ;
14
+ use rustc:: mir:: visit:: Visitor ;
15
+ use rustc:: ty:: { self , TyCtxt } ;
15
16
use rustc:: ty:: item_path;
16
17
use rustc_data_structures:: fx:: FxHashMap ;
17
18
use rustc_data_structures:: indexed_vec:: Idx ;
@@ -125,14 +126,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
125
126
F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) > ,
126
127
{
127
128
let _: io:: Result < ( ) > = do catch {
128
- let mut file = create_dump_file (
129
- tcx,
130
- "mir" ,
131
- pass_num,
132
- pass_name,
133
- disambiguator,
134
- source,
135
- ) ?;
129
+ let mut file = create_dump_file ( tcx, "mir" , pass_num, pass_name, disambiguator, source) ?;
136
130
writeln ! ( file, "// MIR for `{}`" , node_path) ?;
137
131
writeln ! ( file, "// source = {:?}" , source) ?;
138
132
writeln ! ( file, "// pass_name = {}" , pass_name) ?;
@@ -148,15 +142,9 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
148
142
} ;
149
143
150
144
if tcx. sess . opts . debugging_opts . dump_mir_graphviz {
151
- let _: io:: Result < ( ) > = do catch {
152
- let mut file = create_dump_file (
153
- tcx,
154
- "dot" ,
155
- pass_num,
156
- pass_name,
157
- disambiguator,
158
- source,
159
- ) ?;
145
+ let _: io:: Result < ( ) > = do catch {
146
+ let mut file =
147
+ create_dump_file ( tcx, "dot" , pass_num, pass_name, disambiguator, source) ?;
160
148
write_mir_fn_graphviz ( tcx, source. def_id , mir, & mut file) ?;
161
149
Ok ( ( ) )
162
150
} ;
@@ -297,10 +285,10 @@ where
297
285
}
298
286
299
287
/// Write out a human-readable textual representation for the given basic block.
300
- pub fn write_basic_block < F > (
301
- tcx : TyCtxt ,
288
+ pub fn write_basic_block < ' cx , ' gcx , ' tcx , F > (
289
+ tcx : TyCtxt < ' cx , ' gcx , ' tcx > ,
302
290
block : BasicBlock ,
303
- mir : & Mir ,
291
+ mir : & Mir < ' tcx > ,
304
292
extra_data : & mut F ,
305
293
w : & mut Write ,
306
294
) -> io:: Result < ( ) >
@@ -330,6 +318,11 @@ where
330
318
comment( tcx, statement. source_info) ,
331
319
A = ALIGN ,
332
320
) ?;
321
+
322
+ write_extra ( tcx, w, |visitor| {
323
+ visitor. visit_statement ( current_location. block , statement, current_location) ;
324
+ } ) ?;
325
+
333
326
extra_data ( PassWhere :: AfterLocation ( current_location) , w) ?;
334
327
335
328
current_location. statement_index += 1 ;
@@ -346,11 +339,93 @@ where
346
339
comment( tcx, data. terminator( ) . source_info) ,
347
340
A = ALIGN ,
348
341
) ?;
342
+
343
+ write_extra ( tcx, w, |visitor| {
344
+ visitor. visit_terminator ( current_location. block , data. terminator ( ) , current_location) ;
345
+ } ) ?;
346
+
349
347
extra_data ( PassWhere :: AfterLocation ( current_location) , w) ?;
350
348
351
349
writeln ! ( w, "{}}}" , INDENT )
352
350
}
353
351
352
+ /// After we print the main statement, we sometimes dump extra
353
+ /// information. There's often a lot of little things "nuzzled up" in
354
+ /// a statement.
355
+ fn write_extra < ' cx , ' gcx , ' tcx , F > (
356
+ tcx : TyCtxt < ' cx , ' gcx , ' tcx > ,
357
+ write : & mut Write ,
358
+ mut visit_op : F ,
359
+ ) -> io:: Result < ( ) >
360
+ where F : FnMut ( & mut ExtraComments < ' cx , ' gcx , ' tcx > )
361
+ {
362
+ let mut extra_comments = ExtraComments {
363
+ _tcx : tcx,
364
+ comments : vec ! [ ] ,
365
+ } ;
366
+ visit_op ( & mut extra_comments) ;
367
+ for comment in extra_comments. comments {
368
+ writeln ! ( write, "{:A$} // {}" , "" , comment, A = ALIGN ) ?;
369
+ }
370
+ Ok ( ( ) )
371
+ }
372
+
373
+ struct ExtraComments < ' cx , ' gcx : ' tcx , ' tcx : ' cx > {
374
+ _tcx : TyCtxt < ' cx , ' gcx , ' tcx > , // don't need it now, but bet we will soon
375
+ comments : Vec < String > ,
376
+ }
377
+
378
+ impl < ' cx , ' gcx , ' tcx > ExtraComments < ' cx , ' gcx , ' tcx > {
379
+ fn push ( & mut self , lines : & str ) {
380
+ for line in lines. split ( "\n " ) {
381
+ self . comments . push ( line. to_string ( ) ) ;
382
+ }
383
+ }
384
+ }
385
+
386
+ impl < ' cx , ' gcx , ' tcx > Visitor < ' tcx > for ExtraComments < ' cx , ' gcx , ' tcx > {
387
+ fn visit_constant ( & mut self , constant : & Constant < ' tcx > , location : Location ) {
388
+ self . super_constant ( constant, location) ;
389
+ let Constant { span, ty, literal } = constant;
390
+ self . push ( & format ! ( "mir::Constant" ) ) ;
391
+ self . push ( & format ! ( "└ span: {:?}" , span) ) ;
392
+ self . push ( & format ! ( "└ ty: {:?}" , ty) ) ;
393
+ self . push ( & format ! ( "└ literal: {:?}" , literal) ) ;
394
+ }
395
+
396
+ fn visit_const ( & mut self , constant : & & ' tcx ty:: Const < ' tcx > , _: Location ) {
397
+ self . super_const ( constant) ;
398
+ let ty:: Const { ty, val } = constant;
399
+ self . push ( & format ! ( "ty::Const" ) ) ;
400
+ self . push ( & format ! ( "└ ty: {:?}" , ty) ) ;
401
+ self . push ( & format ! ( "└ val: {:?}" , val) ) ;
402
+ }
403
+
404
+ fn visit_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
405
+ self . super_rvalue ( rvalue, location) ;
406
+ match rvalue {
407
+ Rvalue :: Aggregate ( kind, _) => match * * kind {
408
+ AggregateKind :: Closure ( def_id, substs) => {
409
+ self . push ( & format ! ( "closure" ) ) ;
410
+ self . push ( & format ! ( "└ def_id: {:?}" , def_id) ) ;
411
+ self . push ( & format ! ( "└ substs: {:#?}" , substs) ) ;
412
+ }
413
+
414
+ AggregateKind :: Generator ( def_id, substs, interior) => {
415
+ self . push ( & format ! ( "generator" ) ) ;
416
+ self . push ( & format ! ( "└ def_id: {:?}" , def_id) ) ;
417
+ self . push ( & format ! ( "└ substs: {:#?}" , substs) ) ;
418
+ self . push ( & format ! ( "└ interior: {:?}" , interior) ) ;
419
+ }
420
+
421
+ _ => { }
422
+ } ,
423
+
424
+ _ => { }
425
+ }
426
+ }
427
+ }
428
+
354
429
fn comment ( tcx : TyCtxt , SourceInfo { span, scope } : SourceInfo ) -> String {
355
430
format ! (
356
431
"scope {} at {}" ,
0 commit comments