Clarification About `transparent` Type Representation Needed

From the reference:

Structs and enums with this representation have the same layout and ABI as the single non-zero sized field.

Does this also influence the layout guarantee of types with repr(Rust), that contain transparent types? In particular, I have the following types:

struct Mutex<T: ?Sized> {
    locked: AtomicBool,
    value: UnsafeCell<T>,
}

struct MutexGuard<'a, T> {
    mutex: &'a Mutex<T>,
}

Am I allowed to transmute a MutexGuard<'a, MaybeUninit<T>> to MutexGuard<'a, T> (assuming T is initialized)? I suspect not, but I am not entirely sure. I want to keep the layout as flexible as possible.

No, you can't. It wouldn't quite make sense if #[repr(transparent)] worked transitively like that, because then anything that contained a transparent type would also (need to) be transparent.

In general, transmuting references and pointers is not a great idea. As a general rule, before transmuting, peel off as many layers of indirection as you possibly can, because pulling the thread of safety guarantees through layers of indirection is tricky. For example, you are allowed to create a &[u8] from a &[u16] by casting pointers and adjusting the length, then using slice::from_raw_partsdirectly. However, you are not allowed to transmute a &[u16] to a &[u8], much less a Vec<u16> to a Vec<u8>, etc.

1 Like

Yeah, layout guarantees stop at #[repr(Rust)] boundaries: you'd need that struct Mutex to be #[repr(C)], to at least give a consistent layout algorithm to work with (one where T <-> MaybeUninit<T>, for instance, won't affect its layout, thus making the transmute you talk about valid). But without that #[repr(C)], there isn't that much you can do.

Note that, thus, the most important repr() annotation is repr(C): repr(transparent) can be viewed, for starters, as a less usable version of repr(C). In reality, repr(transparent) does imbue the type with an extra capability: that of allowing to transmute fn pointers involving it, which is not allowed for #[repr(C)] wrapper types.

1 Like

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.