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

  1. Remove the stale dump output tree and retry: `rm -rf target/debug/mir` (or your dump dir).
  2. Check disk quota / free inodes (`df -i`, `quota -u`) and free space if EDQUOT/ENOSPC.
  3. Move the dump dir off the problematic mount: pass `-Zdump-mir-dir=<writable-path>`.
  4. 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

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


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/4001dba863f779c1.json. Report an issue: GitHub.