I'm using the
ulid crate and it's
Ulid type is defined as
struct Ulid(pub u128).
I'm trying to understand whether or not the default
#[repr(Rust)] representation guarantees that the
Ulid will have the same memory layout as a
It seems like it's extremely likely to have the same layout, but is it possible that the Rust representation could add like a ghost offset to the
u128 isn't it?
I'm wondering whether or not I need to open a PR to the
ulid crate to see if they are fine adding a
#[repr(transparent)] annotation to the struct.
There is no such guarantee in the default representation. Structures with one field are as undefined in layout as structures with any other number of fields.
The only time you'd need
#[repr(transparent)] is when you need to cast between
&Ulid (or some other POD type), or when using the type in FFI interchangeably with the wrapped type (but
u128 is an FFI nightmare). If you aren't doing those kinds of tricks, it's generally considered preferable to keep the standard layout. The compiler isn't going to just randomly decide to pick a bad layout (unless you ask it to, e.g.
Yeah, I'm looking to be able to cast the
Ulid unsafely to a
u128 for a scripting-type integration.
Oh, really. What's the issue? I'm not exactly using it over FFI yet, since the language I'm going to be scripting with is written in Rust, but the idea would be to FFI friendly probably.
Maybe it'd be better to represent it with two
My current work-around was that I realized that if I validate that the
Layout::new::<Ulid>().size == Layout::new::<u128>().size, then, according to the guarantees about the default representation, I'm pretty sure that we know that the layout is the same.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.