Skip to content

Unions with ZSTs are no longer usable #59126

Closed
@mjbshaw

Description

@mjbshaw

It looks like this was broken in the release of 1.32.0 (and is still broken, even on nightly) (checked on https://rust.godbolt.org/). The following example program:

union Uninit {
    _never_use: *const u8,
    uninit: (),
}

const UNINIT: Uninit = Uninit { uninit: () };

fn main() {
    let _ = UNINIT; // This line isn't actually necessary.
}

Fails to compile:

$ rustc --edition=2018 t.rs
error[E0080]: it is undefined behavior to use this value
 --> t.rs:6:1
  |
6 | const UNINIT: Uninit = Uninit { uninit: () };
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
  |
  = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior

error: aborting due to previous error

For more information about this error, try `rustc --explain E0080`.

Interestingly, making the union #[repr(C)] fixes it.

My Rust version:

$ rustc --version
rustc 1.35.0-nightly (e68bf8ae1 2019-03-11)

I know union field accesses aren't stable, but I don't think this qualifies as a field access. And yes, I'm aware of MaybeUninit.

cc @RalfJung

Metadata

Metadata

Assignees

Labels

A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions