Rust Tooling and Code Quality

Miri

Miri (cargo +nightly miri test) is an Undefined Behavior (UB) detection interpreter for Rust's Mid-level Intermediate Representation (MIR). Instead of compiling Rust code to native machine instructions where undefined behavior might silently appear to work by coincidence on your CPU, Miri interprets the MIR directly in a virtual machine that tracks every byte's initialization state, pointer provenance (Stacked Borrows and Tree Borrows), alignment, and thread synchronization.

Standard `cargo test` (Native CPU):       `cargo +nightly miri test` (MIR Interpreter):
  Raw pointer aliasing / uninit read        Every memory byte carries:
  may accidentally pass on x86_64!          - Initialization bit (Init vs Uninit/Padding)
                                            - Pointer Provenance Tag (Stacked/Tree Borrows)
                                            - Exact Allocation Bounds & Alignment
                                            --> Immediately halts & pinpoints exact UB!

Classes of Undefined Behavior Detected by Miri

Miri deterministically catches memory and concurrency bugs inside unsafe code that ordinary tests miss:

  1. Out-of-bounds pointer arithmetic or dereferences (even by 1 byte).
  2. Use-after-free (dereferencing a dangling pointer after its allocation was dropped or reallocated).
  3. Invalid aliasing violations (violating Rust's Stacked Borrows / Tree Borrows rules by using a raw pointer after a conflicting &mut T reference invalidated its provenance tag).
  4. Reading uninitialized memory (such as reading uninitialized MaybeUninit<T> bytes or struct padding bytes).
  5. Misaligned pointer reads/writes or constructing invalid primitive values (such as a bool that is not 0 or 1, or a null reference).
  6. Memory leaks (allocations still reachable or unreachable when main or a test exits without being freed).
  7. Data races across threads using unsynchronized non-atomic memory accesses.

Installing and Running Miri

Miri is distributed as an official rustup component on the nightly toolchain:

# 1. Install the Miri component on the nightly toolchain
rustup +nightly component add miri

# 2. Run your crate's test suite inside the Miri interpreter
cargo +nightly miri test

# 3. Test with the Tree Borrows aliasing model and random schedule exploration
MIRIFLAGS="-Zmiri-tree-borrows -Zmiri-many-seeds=0..16" cargo +nightly miri test

Example: Writing Provenance-Sound unsafe Code That Passes Miri

A common mistake in unsafe code is creating a mutable reference &mut array[0] and then using that pointer to access adjacent elements ptr.add(1)—which violates Stacked Borrows because &mut array[0] only has provenance over index 0! Using slice.as_mut_ptr() preserves provenance over the entire slice so the code is sound and passes Miri:

/// Swaps two elements in `slice` using raw pointers while preserving slice-wide provenance.
pub fn swap_elements<T>(slice: &mut [T], i: usize, j: usize) {
    assert!(i < slice.len() && j < slice.len(), "index out of bounds");
    if i == j {
        return;
    }

    // Obtain the raw mutable pointer from the ENTIRE slice (`as_mut_ptr()`),
    // NOT from `&mut slice[0]`, so the pointer's provenance covers all indices `0..slice.len()`.
    let base_ptr = slice.as_mut_ptr();

    // SAFETY: `i` and `j` are in-bounds (`< slice.len()`) and `i != j`, so the two
    // pointers are valid, properly aligned, and non-overlapping.
    unsafe {
        let ptr_i = base_ptr.add(i);
        let ptr_j = base_ptr.add(j);
        std::ptr::swap_nonoverlapping(ptr_i, ptr_j, 1);
    }
}

fn main() {
    let mut data = [10, 20, 30, 40];
    swap_elements(&mut data, 0, 3);
    assert_eq!(data, [40, 20, 30, 10]);
    println!("Sound pointer swap verified: {data:?}");
}
Sound pointer swap verified: [40, 20, 30, 10]

Adjusting Test Iteration Counts Under cfg(miri)

Because Miri interprets every MIR statement with full shadow-memory and provenance tracking, code runs roughly 50x–500x slower under Miri than native execution. Use cfg(miri) inside stress tests to run a smaller iteration count when running under Miri while keeping a large iteration count for native cargo test:

#[cfg(miri)]
const STRESS_ITERS: usize = 32;

#[cfg(not(miri))]
const STRESS_ITERS: usize = 100_000;