Due to niche optimization, these don’t necessarily exist as a separate field. Option<&T>, for example, uses a null pointer to represent None instead of a separate tag.
You gotta use the appropriate #[repr(...)] annotations as described in the link above. If you don't do this, the layout of the enum is unspecificed and may change at any time.
Layout is not defined for #[repr(rust)] enums. But you can use #[repr(C)] or #[repr(<int>)] that have a well-defined layout, see The Reference (#[repr(C)], #[repr(<int>)]).
I'm a bit slow on this. If I want a Rust struct/enum that implements Copy to be readable outside of Rust, I should probably, as a rule of thumb, just default to #[repr(C)] for every time "seen" outside of Rust right ?
Yeah. If you don't have #[repr(C)] on your struct/enum, then C must treat it as an opaque type that it can manipulate only by passing it back to Rust code.
@chrefr : Is this (1) an example copy/pasted from somewhere, (2) the output of some tool you ran the rust code through or (3) you just manually simulated the process and wrote it out yourself ?
[I'm hoping for (2) because I don't have faith in my own ability to do (3)].
For repr(Rust) (the default), by definition it's only rustc that knows how to do it (outside of a few defined exceptions like the Option ones). It's intentionally unspecified so that future rustcs can do more optimizations than they do today.
With a non-default repr you can get more guarantees, as alice mentioned.