How to represent `enum XXX<T> {A, B, C(Arc<T>)}` in 8 bytes

Suppose I'm writing a big-integer type with small-number optimization for 0 and 1, while larger integers are stored behind an Arc. When representing this type as an enum, the compiler automatically uses the Arc's null pointer for one additional unit variant (If I understand it correctly). However, if two additional variants are provided, the enum's size will be aligned to 16 (on a 64-bit machine), which is unacceptable to me.

enum Integer<T> {
    Zero,
    Other(Arc<T>)
}; // size = 8

enum Integer<T> {
    Zero,
    One,
    Other(Arc<T>)
}; // size = 16

Is it possible to use other invalid memory addresses to represent both Zero and One?
What is the recommended way to do this?

The compiler currently does not support any "niches" for pointers other than the null one. There are proposals to change that, but none have yet been implemented.

In order to do this, you'll have to do it manually using a raw *const T pointer which you compare against the special values.

1 Like