-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Open
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-exhaustiveness-checkingRelating to exhaustiveness / usefulness checking of patternsRelating to exhaustiveness / usefulness checking of patternsA-miriArea: The miri toolArea: The miri toolA-patternsRelating to patterns and pattern matchingRelating to patterns and pattern matchingC-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-opsemRelevant to the opsem teamRelevant to the opsem team
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:
match
on uninhabited type does not trigger UB in Miri #142394- Adding generics affect whether code has UB or not, according to Miri #146803
- Uninhabited types have strange borrow-checking behavior, even behind references #146590
- Make closure capturing have consistent and correct behaviour around patterns #138961
- Document how closure capturing interacts with discriminant reads reference#1837
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)
Metadata
Metadata
Assignees
Labels
A-MIRArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlArea: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.htmlA-exhaustiveness-checkingRelating to exhaustiveness / usefulness checking of patternsRelating to exhaustiveness / usefulness checking of patternsA-miriArea: The miri toolArea: The miri toolA-patternsRelating to patterns and pattern matchingRelating to patterns and pattern matchingC-discussionCategory: Discussion or questions that doesn't represent real issues.Category: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.Items that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamRelevant to the language teamT-opsemRelevant to the opsem teamRelevant to the opsem team