Skip to content

Inconsistent behavior in irrefutable or-patterns due to UB-removing MIR opt #4237

Open
@theemathas

Description

@theemathas

I ran the following code under miri, and it reported no errors:

use std::mem::MaybeUninit;
fn main() {
    let uninit: MaybeUninit<i32> = MaybeUninit::uninit();
    let bad_ref: &i32 = unsafe { uninit.assume_init_ref() };
    let &(0 | _) = bad_ref;
}

However, changing the 0 to 0.. causes Miri to report undefined behavior:

use std::mem::MaybeUninit;
fn main() {
    let uninit: MaybeUninit<i32> = MaybeUninit::uninit();
    let bad_ref: &i32 = unsafe { uninit.assume_init_ref() };
    let &(0.. | _) = bad_ref;
}

The error reported for the second version of the code:

error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
 --> src/main.rs:5:11
  |
5 |     let &(0.. | _) = bad_ref;
  |           ^^^ using uninitialized data, but this operation requires initialized memory
  |
  = 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:5:11: 5:14

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error

I expected both versions of the code to behave the same.

Discovered while experimenting with rust-lang/rust#138973
cc @cyrgani @meithecatte

Reproducible on the playground with version 1.87.0-nightly (2025-03-26 a2e63569fd6702ac5dd0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions