Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safely treating a `&[T]` as a `&[MaybeUninit<T>]` in Rust

How can/should I obtain a &[MaybeUninit<T>] from a &[T]?

Intuitively, I should be allowed to treat initialized memory as being possibly uninitialized, but intuition and unsafe do not always mix well... Since MaybeUninit<T> is guaranteed to have the same size and alignment as T, it should be safe to transmute a &[T] into a &[MaybeUninit<T>]?

Then again, the current implementation of MaybeUninit::new(val) does more than just transmuting, it adds a ManuallyDrop::new(val) wrapper. Does this mean that if I implemented slice_as_maybeuninit via transmuting, I'd run into problems with destructors not being run? Which is not unsafe, but still undesirable enough to restrict such a function to slices of data that implement Copy (i.e., which do not implement Drop).

To make my question(s) more precise:

  • How should I implement fn slice_as_maybeuninit<'a, T>(s: &'a [T]) -> &'a [MaybeUninit<T>], if at all?
  • How should I implement fn slice_as_maybeuninit<'a, T: Copy>(s: &'a [T]) -> &'a [MaybeUninit<T>]? // note the T: Copy bound
  • Bonus: Why does std::mem::MaybeUninit not provide these operations for me?
like image 629
Aljoscha Meyer Avatar asked Oct 15 '25 04:10

Aljoscha Meyer


1 Answers

A transmutation from [T] to [MaybeUninit<T>] is completely safe. Docs on its layout:

MaybeUninit<T> is guaranteed to have the same size, alignment, and ABI as T:

You do however want to use from_raw_parts to construct the new slice instead of just transmute.

fn slice_as_maybeuninit<T>(s: &[T]) -> &[MaybeUninit<T>] {
    unsafe { std::slice::from_raw_parts(s.as_ptr() as *const MaybeUninit<T>, s.len()) }
}

[Will I] run into problems with destructors not being run?

No. In other circumstances you could, MaybeUninit relaxes the initialization criteria so it won't drop its contents since it alone doesn't know if its contents are initialized. However, you are only transmuting a &[T] which is only a reference to the contents; so it won't try to drop values anyway.

Copy is not necessary since no values of T are being created.

like image 190
kmdreko Avatar answered Oct 17 '25 21:10

kmdreko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!