Introduce MirDumper and MirWriter.

MIR dumping is a mess. There are lots of functions and entry points,
e.g. `dump_mir`, `dump_mir_with_options`, `dump_polonius_mir`,
`dump_mir_to_writer`. Also, it's crucial that `create_dump_file` is
never called without `dump_enabled` first being checked, but there is no
mechanism for ensuring this and it's hard to tell if it is satisfied on
all paths. (`dump_enabled` is checked twice on some paths, however!)

This commit introduces `MirWriter`, which controls the MIR writing, and
encapsulates the `extra_data` closure and `options`. Two existing
functions are now methods of this type. It sets reasonable defaults,
allowing the removal of many `|_, _| Ok(())` closures.

The commit also introduces `MirDumper`, which is layered on top of
`MirWriter`, and which manages the creation of the dump files,
encapsulating pass names, disambiguators, etc. Four existing functions
are now methods of this type.
- `MirDumper::new` will only succeed if dumps are enabled, and will
  return `None` otherwise, which makes it impossible to dump when you
  shouldn't.
- It also sets reasonable defaults for various things like
  disambiguators, which means you no longer need to specify them in many
  cases. When they do need to be specified, it's now done via setter
  methods.
- It avoids some repetition. E.g. `dump_nll_mir` previously specifed the
  pass name `"nll"` four times and the disambiguator `&0` three times;
  now it specifies them just once, to put them in the `MirDumper`.
- For Polonius, the `extra_data` closure can now be specified earlier,
  which avoids having to pass some arguments through some functions.
This commit is contained in:
Nicholas Nethercote
2025-08-15 14:38:17 +10:00
parent 2d21c13405
commit 5ce3797073
14 changed files with 276 additions and 277 deletions

View File

@@ -10,8 +10,7 @@ use std::{io, ops, str};
use regex::Regex;
use rustc_index::bit_set::DenseBitSet;
use rustc_middle::mir::{
self, BasicBlock, Body, Location, create_dump_file, dump_enabled, graphviz_safe_def_name,
traversal,
self, BasicBlock, Body, Location, MirDumper, graphviz_safe_def_name, traversal,
};
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -61,11 +60,13 @@ where
fs::File::create_buffered(&path)?
}
None if dump_enabled(tcx, A::NAME, def_id) => {
create_dump_file(tcx, "dot", false, A::NAME, &pass_name.unwrap_or("-----"), body)?
None => {
let Some(dumper) = MirDumper::new(tcx, A::NAME, body) else {
return Ok(());
};
let disambiguator = &pass_name.unwrap_or("-----");
dumper.set_disambiguator(disambiguator).create_dump_file("dot", body)?
}
_ => return Ok(()),
}
};
let mut file = match file {