Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ use core::{mem::MaybeUninit, ptr};
/// `MaybeUninit::slice_assume_init_mut`. Every element of `slice` must have
/// been initialized.
#[inline(always)]
#[allow(unused_unsafe)] // TODO(MSRV 1.65): Remove this.
pub unsafe fn slice_assume_init_mut<T>(slice: &mut [MaybeUninit<T>]) -> &mut [T] {
let ptr = ptr_from_mut::<[MaybeUninit<T>]>(slice) as *mut [T];
// SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
&mut *(slice as *mut [MaybeUninit<T>] as *mut [T])
unsafe { &mut *ptr }
}

#[inline]
Expand All @@ -18,18 +20,29 @@ pub fn uninit_slice_fill_zero(slice: &mut [MaybeUninit<u8>]) -> &mut [u8] {

#[inline(always)]
pub fn slice_as_uninit<T>(slice: &[T]) -> &[MaybeUninit<T>] {
let ptr = ptr_from_ref::<[T]>(slice) as *const [MaybeUninit<T>];
// SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
// There is no risk of writing a `MaybeUninit<T>` into the result since
// the result isn't mutable.
unsafe { &*(slice as *const [T] as *const [MaybeUninit<T>]) }
unsafe { &*ptr }
}

/// View an mutable initialized array as potentially-uninitialized.
///
/// This is unsafe because it allows assigning uninitialized values into
/// `slice`, which would be undefined behavior.
Comment on lines 30 to 31
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should update this to be:

The caller ensures that the return slice will never be uninitialized.

#[inline(always)]
#[allow(unused_unsafe)] // TODO(MSRV 1.65): Remove this.
pub unsafe fn slice_as_uninit_mut<T>(slice: &mut [T]) -> &mut [MaybeUninit<T>] {
let ptr = ptr_from_mut::<[T]>(slice) as *mut [MaybeUninit<T>];
// SAFETY: `MaybeUninit<T>` is guaranteed to be layout-compatible with `T`.
&mut *(slice as *mut [T] as *mut [MaybeUninit<T>])
unsafe { &mut *ptr }
}

// TODO: MSRV(1.76.0): Replace with `core::ptr::from_mut`.
fn ptr_from_mut<T: ?Sized>(r: &mut T) -> *mut T {
r
}

// TODO: MSRV(1.76.0): Replace with `core::ptr::from_ref`.
fn ptr_from_ref<T: ?Sized>(r: &T) -> *const T {
r
}