Skip to content

less-than ideal representation for enums that contain a large element with multiple niches #145128

@lolbinarycat

Description

@lolbinarycat

I tried this code:

use std::num::NonZero;
enum Enum {
    BigWithNiches((NonZero<u32>, NonZero<u32>)),
    Small1(u16),
    Small2(u16),
}

fn main() {
    dbg!(size_of::<Enum>(), size_of::<Union>());
}

#[repr(C)]
union Union {
    big_with_niches: (NonZero<u32>, NonZero<u32>),
    small: (u32, u16, u16),
}

impl Union {
    fn as_enum(self) -> Enum {
        let (niche, tag, val) = unsafe { self.small };
        if niche == 0 {
            if tag == 0 {
                Enum::Small1(val)
            } else {
                Enum::Small2(val)
            }
        } else {
            Enum::BigWithNiches(unsafe { self.big_with_niches })
        }
    }
}

I expected to see this happen: Both datatypes are the same size

Instead, this happened: rustc is not able to find the optimization that the union implements manually

Meta

rustc --version --verbose:

 1.91.0-nightly

(2025-08-07 2fd855fbfc8239285aa2)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-enumArea: Enums (discriminated unions, or more generally ADTs (algebraic data types))A-layoutArea: Memory layout of typesC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions