giluis

July 31, 2026, 6:33pm 1

Hey!

The following code prints 2. I don’t understand why that happens.
I expected it to print 1, because the payloads are just 6 bits, meaning the discriminant / tag could be stored in the remaining 2 bits of the 8 bits in 1 byte.

const Node = union(enum) {
    Next,
    BranchYes: u6,
    BranchYes: u6,
    Terminal: u6,
};

print("{}",.{@sizeOf(Node)})

Can someone explain to me why this Zig does not make this optimization?

There is a proposal to make this for ?enum{}, maybe they will add it at some point in the future, for now if you absolutely need the optimization you can do this:

const NodeTag = enum(u2) {
    Next,
    BranchYes,
    Terminal,
}

const Node = packed struct(u8) {
    tag: NodeTag,
    payload: packed union(u6) {
        BranchYes: u6,
        Terminal: u6,
    }
};

You will have to do some stuff manually, but it is what it is.