Single-variant exception for `match` consequences for `#[non_exhaustive]`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
bar/src/lib.rs:
#[non_exhaustive]
#[repr(u8)]
pub enum Thing {
One(u8) = 0,
}
src/main.rs:
use std::mem::MaybeUninit;
use bar::Thing;
fn main() {
let buffer: [MaybeUninit<u8>; 2] = [MaybeUninit::uninit(), MaybeUninit::new(0u8)];
let ptr: *const Thing = (&raw const buffer).cast();
unsafe {
match *ptr {
Thing::One(ref _val) => {}
_ => {}
}
}
}
Running the above code in Miri detects UB as follows:
error: Undefined Behavior: reading memory at alloc168[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory
--> src/main.rs:9:15
|
9 | match *ptr {
| ^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `main` at src/main.rs:9:15: 9:19
Uninitialized memory occurred at alloc168[0x0..0x1], in this allocation:
alloc168 (stack variable, size: 2, align: 1) {
__ 00 │ ░.
}
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error
However, if I delete the #[non_exhaustive] line, Miri does not detect any UB.
This seems incorrect. I believe that #[non_exhaustive] is supposed to only affect whether code compiles. It should not affect how code behaves.
It seems that, without #[non_exhaustive], rust does not even read the discriminant. But with #[non_exhaustive], rust does.
Related to:
- #142394
- #146803
- #146590
- https://github.com/rust-lang/rust/pull/138961
- https://github.com/rust-lang/reference/pull/1837
- https://github.com/rust-lang/cargo/issues/16417
- https://github.com/rust-lang/rust/pull/150681
Meta
rustc --version --verbose:
rustc 1.92.0-nightly (844264add 2025-10-14)
binary: rustc
commit-hash: 844264adda6f41ca6d0d61c4bcac0f263fc5072f
commit-date: 2025-10-14
host: aarch64-apple-darwin
release: 1.92.0-nightly
LLVM version: 21.1.3
cargo miri --version:
miri 0.1.0 (844264adda 2025-10-14)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the example from bar/src/lib.rs and src/main.rs with Miri, comparing behavior with and without #[non_exhaustive]. Read the related issues and pull requests listed in the report to understand the intended match and enum semantics. Done means the behavior is resolved or formally clarified with a regression test covering this case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100