Skip to content

Is it UB for a uninhibited type, like the never type, value to exist? #337

Open
@erickt

Description

@erickt

Is it safe to create a value that contains an uninhibited type, like the never type, if that value is never read from? For example:

enum Impossible {}

#[repr(transparent)]
struct Foo {
    value: u8,
    impossible: Impossible,
}

fn main() {
    let x = 5u8;
    let foo: Foo = unsafe { std::mem::transmute(x) };
    println!("{:?}", foo.value);
    match foo.impossible {}
}

This thread suggests that this is UB, because we require the transmute to execute. Running this will warn that the type is unreachable and that the value is uninhabited, but the program will compile, and fail with a SIGILL if the uninhibited value is accessed:

warning: unreachable expression
  --> src/main.rs:12:34
   |
11 |             let foo: Foo = unsafe { std::mem::transmute(x) };
   |                                     ---------------------- any code following this expression is unreachable
12 |                 println!("{:?}", foo.value);
   |                                  ^^^ unreachable expression
   |
   = note: `#[warn(unreachable_code)]` on by default
note: this expression has type `Foo`, which is uninhabited
  --> src/main.rs:11:37
   |
11 |             let foo: Foo = unsafe { std::mem::transmute(x) };
   |                                     ^^^^^^^^^^^^^^^^^^^^^^

warning: unused variable: `foo`
  --> src/main.rs:11:17
   |
11 |             let foo: Foo = unsafe { std::mem::transmute(x) };
   |                 ^^^ help: if this is intentional, prefix it with an underscore: `_foo`
   |
   = note: `#[warn(unused_variables)]` on by default


running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

This came up from a review of hyper's proto::h2 module. It feels a little suspicious to me, but cargo miri didn't complain about it.

(Incidentally it appears this code is unnecessary, so we're trying to remove it).

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