@@ -9,6 +9,7 @@ use polonius_engine::{Algorithm, Output};
9
9
use rustc_data_structures:: fx:: FxIndexMap ;
10
10
use rustc_hir:: def_id:: LocalDefId ;
11
11
use rustc_index:: IndexSlice ;
12
+ use rustc_middle:: mir:: pretty:: { dump_mir_with_options, PrettyPrintMirOptions } ;
12
13
use rustc_middle:: mir:: {
13
14
create_dump_file, dump_enabled, dump_mir, Body , ClosureOutlivesSubject ,
14
15
ClosureRegionRequirements , PassWhere , Promoted ,
@@ -19,7 +20,9 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
19
20
use rustc_mir_dataflow:: move_paths:: MoveData ;
20
21
use rustc_mir_dataflow:: points:: DenseLocationMap ;
21
22
use rustc_mir_dataflow:: ResultsCursor ;
23
+ use rustc_session:: config:: MirIncludeSpans ;
22
24
use rustc_span:: symbol:: sym;
25
+ use tracing:: { debug, instrument} ;
23
26
24
27
use crate :: borrow_set:: BorrowSet ;
25
28
use crate :: consumers:: ConsumerOptions ;
@@ -208,52 +211,90 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
208
211
}
209
212
}
210
213
211
- pub ( super ) fn dump_mir_results < ' tcx > (
214
+ /// `-Zdump-mir=nll` dumps MIR annotated with NLL specific information:
215
+ /// - free regions
216
+ /// - inferred region values
217
+ /// - region liveness
218
+ /// - inference constraints and their causes
219
+ ///
220
+ /// As well as graphviz `.dot` visualizations of:
221
+ /// - the region constraints graph
222
+ /// - the region SCC graph
223
+ pub ( super ) fn dump_nll_mir < ' tcx > (
212
224
infcx : & BorrowckInferCtxt < ' tcx > ,
213
225
body : & Body < ' tcx > ,
214
226
regioncx : & RegionInferenceContext < ' tcx > ,
215
227
closure_region_requirements : & Option < ClosureRegionRequirements < ' tcx > > ,
228
+ borrow_set : & BorrowSet < ' tcx > ,
216
229
) {
217
- if !dump_enabled ( infcx. tcx , "nll" , body. source . def_id ( ) ) {
230
+ let tcx = infcx. tcx ;
231
+ if !dump_enabled ( tcx, "nll" , body. source . def_id ( ) ) {
218
232
return ;
219
233
}
220
234
221
- dump_mir ( infcx. tcx , false , "nll" , & 0 , body, |pass_where, out| {
222
- match pass_where {
223
- // Before the CFG, dump out the values for each region variable.
224
- PassWhere :: BeforeCFG => {
225
- regioncx. dump_mir ( infcx. tcx , out) ?;
226
- writeln ! ( out, "|" ) ?;
227
-
228
- if let Some ( closure_region_requirements) = closure_region_requirements {
229
- writeln ! ( out, "| Free Region Constraints" ) ?;
230
- for_each_region_constraint (
231
- infcx. tcx ,
232
- closure_region_requirements,
233
- & mut |msg| writeln ! ( out, "| {msg}" ) ,
234
- ) ?;
235
+ // We want the NLL extra comments printed by default in NLL MIR dumps (they were removed in
236
+ // #112346). Specifying `-Z mir-include-spans` on the CLI still has priority: for example,
237
+ // they're always disabled in mir-opt tests to make working with blessed dumps easier.
238
+ let options = PrettyPrintMirOptions {
239
+ include_extra_comments : matches ! (
240
+ infcx. tcx. sess. opts. unstable_opts. mir_include_spans,
241
+ MirIncludeSpans :: On | MirIncludeSpans :: Nll
242
+ ) ,
243
+ } ;
244
+ dump_mir_with_options (
245
+ tcx,
246
+ false ,
247
+ "nll" ,
248
+ & 0 ,
249
+ body,
250
+ |pass_where, out| {
251
+ match pass_where {
252
+ // Before the CFG, dump out the values for each region variable.
253
+ PassWhere :: BeforeCFG => {
254
+ regioncx. dump_mir ( tcx, out) ?;
235
255
writeln ! ( out, "|" ) ?;
256
+
257
+ if let Some ( closure_region_requirements) = closure_region_requirements {
258
+ writeln ! ( out, "| Free Region Constraints" ) ?;
259
+ for_each_region_constraint ( tcx, closure_region_requirements, & mut |msg| {
260
+ writeln ! ( out, "| {msg}" )
261
+ } ) ?;
262
+ writeln ! ( out, "|" ) ?;
263
+ }
264
+
265
+ if borrow_set. len ( ) > 0 {
266
+ writeln ! ( out, "| Borrows" ) ?;
267
+ for ( borrow_idx, borrow_data) in borrow_set. iter_enumerated ( ) {
268
+ writeln ! (
269
+ out,
270
+ "| {:?}: issued at {:?} in {:?}" ,
271
+ borrow_idx, borrow_data. reserve_location, borrow_data. region
272
+ ) ?;
273
+ }
274
+ writeln ! ( out, "|" ) ?;
275
+ }
236
276
}
237
- }
238
277
239
- PassWhere :: BeforeLocation ( _) => { }
278
+ PassWhere :: BeforeLocation ( _) => { }
240
279
241
- PassWhere :: AfterTerminator ( _) => { }
280
+ PassWhere :: AfterTerminator ( _) => { }
242
281
243
- PassWhere :: BeforeBlock ( _) | PassWhere :: AfterLocation ( _) | PassWhere :: AfterCFG => { }
244
- }
245
- Ok ( ( ) )
246
- } ) ;
282
+ PassWhere :: BeforeBlock ( _) | PassWhere :: AfterLocation ( _) | PassWhere :: AfterCFG => { }
283
+ }
284
+ Ok ( ( ) )
285
+ } ,
286
+ options,
287
+ ) ;
247
288
248
- // Also dump the inference graph constraints as a graphviz file.
289
+ // Also dump the region constraint graph as a graphviz file.
249
290
let _: io:: Result < ( ) > = try {
250
- let mut file = create_dump_file ( infcx . tcx , "regioncx.all.dot" , false , "nll" , & 0 , body) ?;
291
+ let mut file = create_dump_file ( tcx, "regioncx.all.dot" , false , "nll" , & 0 , body) ?;
251
292
regioncx. dump_graphviz_raw_constraints ( & mut file) ?;
252
293
} ;
253
294
254
- // Also dump the inference graph constraints as a graphviz file.
295
+ // Also dump the region constraint SCC graph as a graphviz file.
255
296
let _: io:: Result < ( ) > = try {
256
- let mut file = create_dump_file ( infcx . tcx , "regioncx.scc.dot" , false , "nll" , & 0 , body) ?;
297
+ let mut file = create_dump_file ( tcx, "regioncx.scc.dot" , false , "nll" , & 0 , body) ?;
257
298
regioncx. dump_graphviz_scc_constraints ( & mut file) ?;
258
299
} ;
259
300
}
0 commit comments