Assuming I have a struct (or enum variant), that is defined as
struct Test(T);
with some type T, how can I get a &'a Test
from &'a T
? Or in other words, is there a way to implement From<&'a T>
for &'a Test
?
Assuming I have a struct (or enum variant), that is defined as
struct Test(T);
with some type T, how can I get a &'a Test
from &'a T
? Or in other words, is there a way to implement From<&'a T>
for &'a Test
?
It can be done for a struct with unsafe code if the struct is marked with #[repr(transparent)]
. The bytemuck crate provides a deriveable TransparentWrapper
that provides this functionality and ensures the unsafe code is correct.
I think you can do the same manually for enums if the enum only has a single variant, but the TransparentWrapper
derive only supports structs.
Thank you! I guess for enums with multiple variants this won't work without cloning as the things have an incompatible layout?
If I remember right, then one common mistake is to transmute the references (while it's only correct to transmute raw pointers).
Yep. You would need to create a new instance of your enum somewhere and take a reference to it, whether that is by making a copy of the T
on the heap and leaking it or however you decided to implement it.
To elaborate on your comment about layouts - the allocation referred to by &T
only contains std::mem::size_of::<T>()
number of bytes, but an enum with multiple variants would need to point to std::mem::size_of::<T>() + size_of_tag
number of bytes. Obviously, if we took a &T
and naively transmuted it to an &EnumContainingT
, we would be able to access data outside the original variable's allocation (e.g. by reading other things on the heap or nearby stack variables).