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

Code before:

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);
    }
}

impl<T: Copy> SpecFill<T> for [MaybeUninit<T>] {
    fn spec_fill(&mut self, value: T) {
        self.fill(MaybeUninit::new(value));
    }
}


Review comment (suggestion):
One last thing I noticed, does `ptr::from_ref(self).cast::<[MaybeUninit<T>; N]>()` work here? More clear to read since it avoids the repeated type.

(Same for the `AsMut` impl)

Code after:
    ///
    /// let data: [MaybeUninit<u8>; 1000] = MaybeUninit::uninit().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) }
    }
}

#[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()
    }
}

#[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)
    }