Repository: rust-lang/rust
File: library/core/src/mem/maybe_uninit.rs (Rust)

Code before:
    /// Transposes a `[MaybeUninit<T>; N]` into a `MaybeUninit<[T; N]>`.
    ///
    /// # Examples
    ///
    /// ```
    /// #![feature(maybe_uninit_uninit_array_transpose)]
    /// # use std::mem::MaybeUninit;
    ///
    /// let data = [MaybeUninit::<u8>::uninit(); 1000];
    /// let data: MaybeUninit<[u8; 1000]> = data.transpose();
    /// ```
    #[unstable(feature = "maybe_uninit_uninit_array_transpose", issue = "96097")]
    #[inline]
    pub const fn transpose(self) -> MaybeUninit<[T; N]> {
        // SAFETY: T and MaybeUninit<T> have the same layout
        unsafe { intrinsics::transmute_unchecked(self) }
    }
}

struct Guard<'a, T> {
    slice: &'a mut [MaybeUninit<T>],
    initialized: usize,
}

impl<'a, T> Drop for Guard<'a, T> {
    fn drop(&mut self) {
        let initialized_part = &mut self.slice[..self.initialized];
        // SAFETY: this raw sub-slice will contain only initialized objects.
        unsafe {
            initialized_part.assume_init_drop();
        }
    }
}

trait SpecFill<T> {
    fn spec_fill(&mut self, value: T);
}

impl<T: Clone> SpecFill<T> for [MaybeUninit<T>] {
    default fn spec_fill(&mut self, value: T) {
        let mut guard = Guard { slice: self, initialized: 0 };

        if let Some((last, elems)) = guard.slice.split_last_mut() {
            for el in elems {
                el.write(value.clone());
                guard.initialized += 1;
            }

            last.write(value);
        }
        super::forget(guard);

Review comment (suggestion):
Is there a strong reason to not have `impl<T, const N: usize> AsMut<MaybeUninit<[T; N]>> for [MaybeUninit<T>; N]` too?

And I have a few places where bridging APIs could benefit from `impl<T, const N: usize> AsMut<MaybeUninit<[T; N]>> for [T; N]` too, which today requires `transmute()`.

Code after:
impl<T, const N: usize> From<[MaybeUninit<T>; N]> for MaybeUninit<[T; N]> {
    #[inline]
    fn from(arr: [MaybeUninit<T>; N]) -> Self {
        arr.transpose()
    }
}

#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")]
impl<T, const N: usize> AsRef<[MaybeUninit<T>; N]> for MaybeUninit<[T; N]> {
    #[inline]
    fn as_ref(&self) -> &[MaybeUninit<T>; N] {
        // SAFETY: T and MaybeUninit<T> have the same layout
        unsafe { &*ptr::from_ref(self).cast() }
    }
}

#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")]
impl<T, const N: usize> AsRef<[MaybeUninit<T>]> for MaybeUninit<[T; N]> {
    #[inline]
    fn as_ref(&self) -> &[MaybeUninit<T>] {
        &*AsRef::<[MaybeUninit<T>; N]>::as_ref(self)
    }
}

#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")]
impl<T, const N: usize> AsMut<[MaybeUninit<T>; N]> for MaybeUninit<[T; N]> {
    #[inline]
    fn as_mut(&mut self) -> &mut [MaybeUninit<T>; N] {
        // SAFETY: T and MaybeUninit<T> have the same layout
        unsafe { &mut *ptr::from_mut(self).cast() }
    }
}

#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")]
impl<T, const N: usize> AsMut<[MaybeUninit<T>]> for MaybeUninit<[T; N]> {
    #[inline]
    fn as_mut(&mut self) -> &mut [MaybeUninit<T>] {
        &mut *AsMut::<[MaybeUninit<T>; N]>::as_mut(self)
    }
}

#[stable(feature = "more_conversion_trait_impls", since = "CURRENT_RUSTC_VERSION")]
impl<T, const N: usize> From<MaybeUninit<[T; N]>> for [MaybeUninit<T>; N] {
    #[inline]
    fn from(arr: MaybeUninit<[T; N]>) -> Self {
        arr.transpose()
    }
}

impl<T, const N: usize> [MaybeUninit<T>; N] {
    /// Transposes a `[MaybeUninit<T>; N]` into a `MaybeUninit<[T; N]>`.