Currently, Rust has two main ways of ordering the struct fields: repr(Rust)
and repr(C)
. These two ways are the two extremes: repr(Rust)
basically doesn't guarantee anything, while repr(C)
forces the fields to be ordered exactly as declared.
However, these extremes clash with generics and sound type casting. Let's say you have struct Foo<A> { foo: u32, bar: A }
and for some reason you need to do some kind of conversion between Foo<T>
and Foo<U>
where T
and U
have compatible layout (in that direction). If the struct is repr(Rust)
then you cannot do such conversion by transmuting because it'd be unsound. You can write safe code, which works but adds overhead in case the fields actually do end up being in different order. OTOH, there repr(C)
which allows the transmute but wastes space in some cases because no reordering is allowed.
What's needed is a third repr
, let's call it repr(consistent)
here: it guarantees that as long as the individual generic fields are layout-compatible the transmute is sound but no other guarantees are given. So the fields can still be reordered if Foo<A>
and Foo<B>
would not be allowed to be transmuted anyway. Note that repr(transparent)
does this but only for one-field structs but this is needed for multiple-field structs.
I tried to find anything on this topic but couldn't, did nobody need this?
Notably, one obvious limitation is what to do about conversions between say u32
and [u8; 4]
. They have different alignment, so struct reordering would be useful, but same size so casting would be also useful. Maybe having two reprs to cover both use cases would make sense.