@@ -25,6 +25,22 @@ const INDENT: &'static str = " ";
2525/// Alignment for lining up comments following MIR statements
2626const ALIGN : usize = 40 ;
2727
28+ /// An indication of where we are in the control flow graph. Used for printing
29+ /// extra information in `dump_mir`
30+ pub enum PassWhere {
31+ /// We have not started dumping the control flow graph, but we are about to.
32+ BeforeCFG ,
33+
34+ /// We just finished dumping the control flow graph. This is right before EOF
35+ AfterCFG ,
36+
37+ /// We are about to start dumping the given basic block.
38+ BeforeBlock ( BasicBlock ) ,
39+
40+ /// We are just about to dumpt the given statement or terminator.
41+ InCFG ( Location ) ,
42+ }
43+
2844/// If the session is properly configured, dumps a human-readable
2945/// representation of the mir into:
3046///
@@ -39,12 +55,16 @@ const ALIGN: usize = 40;
3955/// - `substring1&substring2,...` -- `&`-separated list of substrings
4056/// that can appear in the pass-name or the `item_path_str` for the given
4157/// node-id. If any one of the substrings match, the data is dumped out.
42- pub fn dump_mir < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
43- pass_num : Option < ( MirSuite , MirPassIndex ) > ,
44- pass_name : & str ,
45- disambiguator : & Display ,
46- source : MirSource ,
47- mir : & Mir < ' tcx > ) {
58+ pub fn dump_mir < ' a , ' tcx , F > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
59+ pass_num : Option < ( MirSuite , MirPassIndex ) > ,
60+ pass_name : & str ,
61+ disambiguator : & Display ,
62+ source : MirSource ,
63+ mir : & Mir < ' tcx > ,
64+ extra_data : F )
65+ where
66+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
67+ {
4868 if !dump_enabled ( tcx, pass_name, source) {
4969 return ;
5070 }
@@ -53,12 +73,7 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
5373 tcx. item_path_str ( tcx. hir . local_def_id ( source. item_id ( ) ) )
5474 } ) ;
5575 dump_matched_mir_node ( tcx, pass_num, pass_name, & node_path,
56- disambiguator, source, mir) ;
57- for ( index, promoted_mir) in mir. promoted . iter_enumerated ( ) {
58- let promoted_source = MirSource :: Promoted ( source. item_id ( ) , index) ;
59- dump_matched_mir_node ( tcx, pass_num, pass_name, & node_path, disambiguator,
60- promoted_source, promoted_mir) ;
61- }
76+ disambiguator, source, mir, extra_data) ;
6277}
6378
6479pub fn dump_enabled < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
@@ -85,13 +100,17 @@ pub fn dump_enabled<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
85100// `item_path_str()` would otherwise trigger `type_of`, and this can
86101// run while we are already attempting to evaluate `type_of`.
87102
88- fn dump_matched_mir_node < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
89- pass_num : Option < ( MirSuite , MirPassIndex ) > ,
90- pass_name : & str ,
91- node_path : & str ,
92- disambiguator : & Display ,
93- source : MirSource ,
94- mir : & Mir < ' tcx > ) {
103+ fn dump_matched_mir_node < ' a , ' tcx , F > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
104+ pass_num : Option < ( MirSuite , MirPassIndex ) > ,
105+ pass_name : & str ,
106+ node_path : & str ,
107+ disambiguator : & Display ,
108+ source : MirSource ,
109+ mir : & Mir < ' tcx > ,
110+ mut extra_data : F )
111+ where
112+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
113+ {
95114 let promotion_id = match source {
96115 MirSource :: Promoted ( _, id) => format ! ( "-{:?}" , id) ,
97116 MirSource :: GeneratorDrop ( _) => format ! ( "-drop" ) ,
@@ -125,7 +144,9 @@ fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
125144 writeln ! ( file, "// generator_layout = {:?}" , layout) ?;
126145 }
127146 writeln ! ( file, "" ) ?;
128- write_mir_fn ( tcx, source, mir, & mut file) ?;
147+ extra_data ( PassWhere :: BeforeCFG , & mut file) ?;
148+ write_mir_fn ( tcx, source, mir, & mut extra_data, & mut file) ?;
149+ extra_data ( PassWhere :: AfterCFG , & mut file) ?;
129150 Ok ( ( ) )
130151 } ) ;
131152}
@@ -152,24 +173,29 @@ pub fn write_mir_pretty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
152173
153174 let id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
154175 let src = MirSource :: from_node ( tcx, id) ;
155- write_mir_fn ( tcx, src, mir, w) ?;
176+ write_mir_fn ( tcx, src, mir, & mut |_ , _| Ok ( ( ) ) , w) ?;
156177
157178 for ( i, mir) in mir. promoted . iter_enumerated ( ) {
158179 writeln ! ( w, "" ) ?;
159- write_mir_fn ( tcx, MirSource :: Promoted ( id, i) , mir, w) ?;
180+ write_mir_fn ( tcx, MirSource :: Promoted ( id, i) , mir, & mut |_ , _| Ok ( ( ) ) , w) ?;
160181 }
161182 }
162183 Ok ( ( ) )
163184}
164185
165- pub fn write_mir_fn < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
166- src : MirSource ,
167- mir : & Mir < ' tcx > ,
168- w : & mut Write )
169- -> io:: Result < ( ) > {
186+ pub fn write_mir_fn < ' a , ' tcx , F > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
187+ src : MirSource ,
188+ mir : & Mir < ' tcx > ,
189+ extra_data : & mut F ,
190+ w : & mut Write )
191+ -> io:: Result < ( ) >
192+ where
193+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
194+ {
170195 write_mir_intro ( tcx, src, mir, w) ?;
171196 for block in mir. basic_blocks ( ) . indices ( ) {
172- write_basic_block ( tcx, block, mir, w) ?;
197+ extra_data ( PassWhere :: BeforeBlock ( block) , w) ?;
198+ write_basic_block ( tcx, block, mir, extra_data, w) ?;
173199 if block. index ( ) + 1 != mir. basic_blocks ( ) . len ( ) {
174200 writeln ! ( w, "" ) ?;
175201 }
@@ -180,11 +206,15 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
180206}
181207
182208/// Write out a human-readable textual representation for the given basic block.
183- pub fn write_basic_block ( tcx : TyCtxt ,
184- block : BasicBlock ,
185- mir : & Mir ,
186- w : & mut Write )
187- -> io:: Result < ( ) > {
209+ pub fn write_basic_block < F > ( tcx : TyCtxt ,
210+ block : BasicBlock ,
211+ mir : & Mir ,
212+ extra_data : & mut F ,
213+ w : & mut Write )
214+ -> io:: Result < ( ) >
215+ where
216+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
217+ {
188218 let data = & mir[ block] ;
189219
190220 // Basic block label at the top.
@@ -195,6 +225,7 @@ pub fn write_basic_block(tcx: TyCtxt,
195225 // List of statements in the middle.
196226 let mut current_location = Location { block : block, statement_index : 0 } ;
197227 for statement in & data. statements {
228+ extra_data ( PassWhere :: InCFG ( current_location) , w) ?;
198229 let indented_mir = format ! ( "{0}{0}{1:?};" , INDENT , statement) ;
199230 writeln ! ( w, "{0:1$} // {2}" ,
200231 indented_mir,
@@ -205,6 +236,7 @@ pub fn write_basic_block(tcx: TyCtxt,
205236 }
206237
207238 // Terminator at the bottom.
239+ extra_data ( PassWhere :: InCFG ( current_location) , w) ?;
208240 let indented_terminator = format ! ( "{0}{0}{1:?};" , INDENT , data. terminator( ) . kind) ;
209241 writeln ! ( w, "{0:1$} // {2}" ,
210242 indented_terminator,
0 commit comments