Skip to content

Dead variant removal in #[repr(C)] enums #500

Closed
@GoldsteinE

Description

@GoldsteinE

Consider this enum:

#[repr(C)]
enum Fun<T> {
    Fun(T),
    // maybe some other variants here
}

For unsafe code it could be useful to assume that Fun<T> is layout-compatible with Fun<MaybeUninit<T>> for any choice of T. That’s not currently the case: if T is uninhabited, Fun<T> would be zero-sized (or, more generally, the ::Fun variant will not affect enum size), but Fun<MaybeUninit<T>> wouldn’t.

Reference currently documents the above enum as being rough equivalent to something like

#[repr(C)]
enum FunDiscriminant {
    Fun,
}

#[repr(C)]
union FunData<T> {
    fun: T,
}

#[repr(C)]
struct Fun<T> {
    discriminant: FunDiscriminant,
    data: FunData<T>,
}

That doesn’t hold for uninhabited types: this “desugaring” preserves the invariant above.

I think we should do one of the following:

  1. Either dead variant removal should be disabled for #[repr(C)] enums;
  2. or it should be documented in the reference (I can write the patch if this option is selected).

Related: #443
Playground demonstrating the issue: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d2995ff99cea9c2e60d28cbf0f970176

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