rust-lang/rust · error · io::Error
IO error creating MIR dump file: {file_path:?}; {e}
Error message
IO error creating MIR dump file: {file_path:?}; {e} What it means
`create_dump_file`'s second I/O site: `fs::File::create_buffered(&file_path)` fails after the directory was created. rustc_middle wraps the OS error into a descriptive io::Error so the MIR-dump subsystem can report which file it could not open. Causes are filesystem-level (permission, read-only, name too long, EDQUOT) rather than MIR-level.
Source
Thrown at compiler/rustc_middle/src/mir/pretty.rs:305
/// bit of MIR-related data. Used by `mir-dump`, but also by other
/// bits of code (e.g., NLL inference) that dump graphviz data or
/// other things, and hence takes the extension as an argument.
pub fn create_dump_file(
&self,
extension: &str,
body: &Body<'tcx>,
) -> io::Result<io::BufWriter<fs::File>> {
let file_path = self.dump_path(extension, body);
if let Some(parent) = file_path.parent() {
fs::create_dir_all(parent).map_err(|e| {
io::Error::new(
e.kind(),
format!("IO error creating MIR dump directory: {parent:?}; {e}"),
)
})?;
}
fs::File::create_buffered(&file_path).map_err(|e| {
io::Error::new(e.kind(), format!("IO error creating MIR dump file: {file_path:?}; {e}"))
})
}
}
///////////////////////////////////////////////////////////////////////////
// Whole MIR bodies
/// Write out a human-readable textual representation of this crate's MIR,
/// with the default [`PrettyPrintMirOptions`].
pub fn write_mir_pretty<'tcx>(tcx: TyCtxt<'tcx>, w: &mut dyn io::Write) -> io::Result<()> {
let writer = MirWriter::new(tcx);
writeln!(w, "// WARNING: This output format is intended for human consumers only")?;
writeln!(w, "// and is subject to change without notice. Knock yourself out.")?;
writeln!(w, "// HINT: See also -Z dump-mir for MIR at specific points during compilation.")?;
let mut first = true;
for &def_id in tcx.mir_keys(()) {View on GitHub (pinned to 22057b88b0)
Solutions
- Remove the stale dump output tree and retry: `rm -rf target/debug/mir` (or your dump dir).
- Check disk quota / free inodes (`df -i`, `quota -u`) and free space if EDQUOT/ENOSPC.
- Move the dump dir off the problematic mount: pass `-Zdump-mir-dir=<writable-path>`.
- On Windows/AV environments, add an exclusion for the build dir, or shorten the crate/disambiguator names producing path-length failures.
Example fix
# before RUSTFLAGS='-Zdump-mir=all' cargo build # error: IO error creating MIR dump file: ".../mir/<crate>.foo.mir"; Quota exceeded (os error 122) # after quota -u $USER # inspect; free space, then: rm -rf target/debug/mir && RUSTFLAGS='-Zdump-mir=all' cargo build
Defensive patterns
Strategy: validation
Validate before calling
// Same surface as [253], but for the file-create step.
// Pre-check path writability and that it is not a directory / read-only file.
use std::path::Path;
fn dump_file_creatable(path: &Path) -> std::io::Result<()> {
if path.is_dir() {
return Err(std::io::Error::new(std::io::ErrorKind::IsADirectory, "path is a directory"));
}
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
// probe-create then remove, so we know File::create will succeed
let _ = std::fs::OpenOptions::new().create_new(true).write_new(true).open(path)
.map(|f| drop(f));
let _ = std::fs::remove_file(path);
Ok(())
} Try / catch
// create_dump_file returns io::Result; branch on it per file.
let result = body.create_dump_file(extension, &body);
match result {
Ok(mut writer) => {
if let Err(e) = render_mir(&mut writer, &body) {
eprintln!("warning: MIR write failed for {extension}: {e}");
}
}
Err(e) => {
// file-level failure: log file_path, continue with the next body
eprintln!("warning: MIR dump file {} could not be created: {e}", extension);
}
} Prevention
- Ensure the dump path's parent exists and is writable (see [253]); a missing parent is the most common cause of the file-create failure too.
- Avoid path collisions: include the body's def_id / pass name in the dump filename so two bodies don't fight over the same file.
- Watch for read-only filesystems (overlay/remount, Docker read-only root) — these surface here even when the directory exists.
- Treat dump creation as best-effort; never let a single failed dump file abort the whole compile.
When it happens
Trigger: Triggered when the dump directory was created (or already existed) but opening the individual `*.mir`/`.dot`/etc. file for writing returns Err — e.g. the path already exists as a directory, the FS rejects the name, or the volume filled between mkdir and create.
Common situations: Quota exhaustion (EDQUOT) on shared CI runners mid-build; a leftover directory with the same name as the dump file from a previous broken run; SELinux/AppArmor denying file creation under `target/`; path-length limits on Windows; antivirus locking newly created files on Windows.
Related errors
- IO error creating MIR dump directory: {parent:?}; {e}
- Failed to remove {path}: {err}
- Failed to read contents of {path}: {err}
- Failed to remove {path}: {err}
- couldn't open rlib
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/4001dba863f779c1.json.
Report an issue: GitHub.