Overview
Miri executes your program by interpreting rustc's MIR instead of compiling it,
checking every memory access against Rust's operational rules as it goes. Its job is the
one the type system can't do: policing unsafe blocks. Where the borrow checker proves
safe code correct statically, miri catches what unsafe code does wrong dynamically —
use-after-free, out-of-bounds access, uninitialized reads, aliasing-model violations,
even data races. No JVM or Go analog exists because no other mainstream ecosystem lets
you opt out of safety and then offers a tool to audit the opt-out.
Key points
- Nightly component:
rustup +nightly component add miri, thencargo +nightly miri test— runs the test suite interpreted. Expect 10–100× slowdown; scope it to the crates/tests that contain or exerciseunsafe. - What it catches: heap UB (use-after-free, double-free, OOB), invalid values (uninitialized reads, bad enum discriminants, null references), aliasing violations per the Tree Borrows / Stacked Borrows experimental models, memory leaks, and data races on the interpreted thread schedule.
- What it can't: FFI calls (no C code to interpret — it errors or shims them), inline asm, and it only sees UB on executed paths — it is a dynamic tool; coverage is your test suite's coverage.
- The aliasing models are the point:
&mutuniqueness is Rust's core promise, and raw-pointer code violating it is UB even when it "works". Miri is the only tool that checks this — LLVM sanitizers can't, they don't know Rust's rules. - Randomized execution: seeds vary alignments, allocation addresses and thread
interleavings (
-Zmiri-many-seedsto sweep) — flushing out latent assumptions. - CI posture: any crate with meaningful
unsaferuns miri in CI on its unsafe-heavy test subset; pair with#[deny(unsafe_op_in_unsafe_fn)]and cargo-geiger for the audit trail. - Also a UB oracle for dependencies: running your suite under miri interprets your deps' code too — how several ecosystem-wide soundness bugs were found.
Examples
rustup +nightly component add miri
cargo +nightly miri test -p my-unsafe-crate
MIRIFLAGS="-Zmiri-many-seeds=0..16" cargo +nightly miri test unsafe_ring_buffer
Related
- The Rust toolchain — parent catalog.
- rustc — the MIR this tool interprets.
- Deep dive Rust — the ownership rules miri enforces dynamically where the borrow checker can't reach.
- Security testing — miri's place in the unsafe audit toolbox beside cargo-geiger and fuzzing.