One thing Rust could really use are anonymous unions (A | B |C instead of E::A(A), E::B(B), E::C(C)). They are to enums what tuple types are to structs.
Another thing that a new language designer might consider is a mechanism to control the layout. For example say I have a pair of nested enums
enum A {
A0(B),
...
A15(B),
}
enum B {
B0,
...
B15,
}
The outer enum A can be represented as `u8` where the upper nibble is the tag for `A` and the lower nibble is the value of `B`.This is kind of a niche thing, but you see it in binary protocols from time to time and losing the ergonomics of enum/match because the enum can't represent your data without widening it is a shame.
Another problem that shows up is this
enum E {
A = 0
B = 1,
Rest(u8),
}
This can't be represented in 1 byte because `Rest` could be 0 or 1. There's no way to tell the compiler that the value of E::Rest is disjoint from any other values in the enum definition - the only way is to add `Rest1, Rest2, ...` variants for all possible values of the underlying data.This problem crops up when you use the `zerocopy` crate.
And finally something that is super difficult to reason about (and has many implications) is storing the tag out-of-band of the enum data. I believe Zig can do this, but I'm not sure much how it works.
These are super minor gripes about using enums in Rust, but I feel like not enough discussion goes towards some of their limitations and tradeoffs, particularly for high performance applications.