Skip to content

match on an enum with a single inhabited variant does not read discriminant #4778

@RalfJung

Description

@RalfJung

Examples by @meithecatte; Cc @Nadrieril
The following code should likely trigger UB, but currently Miri raises no error:

#![feature(never_type)]

#[repr(C)]
#[allow(dead_code)]
enum E {
  V1, // discriminant: 0
  V2(!), // 1
}

fn main() {
    assert_eq!(std::mem::size_of::<E>(), 4);

    let val = 1u32;
    let ptr = (&raw const val).cast::<E>();
    let r = unsafe { &*ptr };
    match r { //~ we'd probably want ERROR: read discriminant of an uninhabited enum variant
        E::V1 => {}
        E::V2(_) => {}
    }
}

The same goes for this variant that adds a closure (to check interactions with rust-lang/rust#138961):

#![feature(never_type)]

#[repr(C)]
#[allow(dead_code)]
enum E {
  V0, // discriminant: 0
  V2(!), // 2
}

fn main() {
    assert_eq!(std::mem::size_of::<E>(), 4);

    let val = 2u32;
    let ptr = (&raw const val).cast::<E>();
    let r = unsafe { &*ptr };
    let f = || {
        // After rust-lang/rust#138961, constructing the closure performs a reborrow of r.
        // Nevertheless, the discriminant is only actually inspected when the closure
        // is called.
        match r { //~ ERROR: read discriminant of an uninhabited enum variant
            E::V0 => {}
            E::V2(_) => {}
        }
    };

    f();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-mirArea: this is about the MIR that we are executing, not about how we are executing itC-bugCategory: This is a bug.I-misses-theoretical-UBImpact: Miri does not report UB when it should, but codegen also "misses" this UB

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions