31
Miri
Miri is a Rust interpreter for MIR — the compiler's mid-level IR. It runs your program's tests one MIR statement at a time, with full provenance tracking, and screams the moment you violate the abstract machine. It's the only tool that will catch the bug from the previous section.
- Miri ships as a rustup component on the nightly toolchain. Install once, then
cargo +nightly miri testruns your test suite under Miri. It is slow — expect 50–500x slowdown — but it is exhaustive.$ rustup toolchain install nightly $ rustup +nightly component add miri $ cargo +nightly miri test - Run it against the previous section's queue. Miri flags the first deref of
self.tailafter the box has been moved, with a stacked-borrows trace pointing at the offending tag.error: Undefined Behavior: trying to retag from <1234> for SharedReadWrite permission, but that tag does not exist in the borrow stack for this location --> src/lib.rs:23:13 | 23 | unsafe { (*self.tail).next = Some(new_node); } | ^^^^^^^^^^^^^^^^ | | | trying to retag from <1234> for SharedReadWrite permission | <1234> was created by a SharedReadWrite retag at offsets [0..24] = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental - Miri does not just run on tests — it runs on any binary or example. Use
MIRIFLAGS="-Zmiri-tree-borrows"to switch from stacked borrows to the newer tree-borrows model; some programs that fail under stacked borrows pass under tree borrows and vice versa. The lesson: write code that satisfies both.$ cargo +nightly miri test # stacked borrows (default) $ MIRIFLAGS="-Zmiri-tree-borrows" cargo +nightly miri test # tree borrows