I was trying to see if I could represent roc tag unions with regular rust enums with #[repr(C)], and it looks like their memory layouts are perfectly compatible except the discriminant is stored at the end rather than the start like in Rust (or generally in C). I thought it might be to pack the discriminant in with fields of the same alignment to avoid unnecessary padding but that doesn't seem to be the case. It's got me curious about whether the ordering was an arbitrary decision? or if putting the discriminant last is advantageous somehow?
It was to reduce padding.
That said, implementation may be bugged or you may not be giving an example where it applies
If you have something like
MyTag : [
A I64 I32 I16 I8,
B,
]
It should pack into 16 bytes
With tag first it would need to be 24 bytes
Makes sense. It does seem to be bugged then. Roc glue reported your example's tag union's discriminantOffset to be 16, where optimally it would be 15
Should I file an issue for this?
yes please
Last updated: Jul 06 2025 at 12:14 UTC