Skip to content

Commit

Permalink
Auto merge of #76217 - RalfJung:maybe-uninit-slice, r=KodrAus
Browse files Browse the repository at this point in the history
rename MaybeUninit slice methods

The `first` methods conceptually point to the whole slice, not just its first element, so rename them to be consistent with the raw ptr methods on ref-slices.

Also, do the equivalent of #76047 for the slice reference getters, and make them part of #63569 (so far they somehow had no tracking issue).

* first_ptr -> slice_as_ptr
* first_ptr_mut -> slice_as_mut_ptr
* slice_get_ref -> slice_assume_init_ref
* slice_get_mut -> slice_assume_init_mut
  • Loading branch information
bors committed Sep 5, 2020
2 parents de921ab + 3506832 commit cdc8f06
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 79 deletions.
26 changes: 15 additions & 11 deletions library/alloc/src/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,11 +474,15 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {

impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
fn into_key_slice(self) -> &'a [K] {
unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len()) }
unsafe {
slice::from_raw_parts(MaybeUninit::slice_as_ptr(&self.as_leaf().keys), self.len())
}
}

fn into_val_slice(self) -> &'a [V] {
unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len()) }
unsafe {
slice::from_raw_parts(MaybeUninit::slice_as_ptr(&self.as_leaf().vals), self.len())
}
}
}

Expand All @@ -493,7 +497,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
// SAFETY: The keys of a node must always be initialized up to length.
unsafe {
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys),
MaybeUninit::slice_as_mut_ptr(&mut (*self.as_leaf_mut()).keys),
self.len(),
)
}
Expand All @@ -503,7 +507,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
// SAFETY: The values of a node must always be initialized up to length.
unsafe {
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).vals),
MaybeUninit::slice_as_mut_ptr(&mut (*self.as_leaf_mut()).vals),
self.len(),
)
}
Expand All @@ -519,10 +523,10 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
let leaf = self.as_leaf_mut();
// SAFETY: The keys and values of a node must always be initialized up to length.
let keys = unsafe {
slice::from_raw_parts_mut(MaybeUninit::first_ptr_mut(&mut (*leaf).keys), len)
slice::from_raw_parts_mut(MaybeUninit::slice_as_mut_ptr(&mut (*leaf).keys), len)
};
let vals = unsafe {
slice::from_raw_parts_mut(MaybeUninit::first_ptr_mut(&mut (*leaf).vals), len)
slice::from_raw_parts_mut(MaybeUninit::slice_as_mut_ptr(&mut (*leaf).vals), len)
};
(keys, vals)
}
Expand All @@ -536,9 +540,9 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::ValMut<'a>, K, V, Type> {
let len = self.len();
let leaf = self.node.as_ptr();
// SAFETY: The keys and values of a node must always be initialized up to length.
let keys = unsafe { slice::from_raw_parts(MaybeUninit::first_ptr(&(*leaf).keys), len) };
let keys = unsafe { slice::from_raw_parts(MaybeUninit::slice_as_ptr(&(*leaf).keys), len) };
let vals = unsafe {
slice::from_raw_parts_mut(MaybeUninit::first_ptr_mut(&mut (*leaf).vals), len)
slice::from_raw_parts_mut(MaybeUninit::slice_as_mut_ptr(&mut (*leaf).vals), len)
};
(keys, vals)
}
Expand Down Expand Up @@ -617,7 +621,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
slice_insert(self.vals_mut(), 0, val);
slice_insert(
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut self.as_internal_mut().edges),
MaybeUninit::slice_as_mut_ptr(&mut self.as_internal_mut().edges),
self.len() + 1,
),
0,
Expand Down Expand Up @@ -675,7 +679,7 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
ForceResult::Internal(mut internal) => {
let edge = slice_remove(
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut internal.as_internal_mut().edges),
MaybeUninit::slice_as_mut_ptr(&mut internal.as_internal_mut().edges),
old_len + 1,
),
0,
Expand Down Expand Up @@ -962,7 +966,7 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::

slice_insert(
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut self.node.as_internal_mut().edges),
MaybeUninit::slice_as_mut_ptr(&mut self.node.as_internal_mut().edges),
self.node.len(),
),
self.idx + 1,
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/array/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl<T, const N: usize> IntoIter<T, N> {
// SAFETY: We know that all elements within `alive` are properly initialized.
unsafe {
let slice = self.data.get_unchecked(self.alive.clone());
MaybeUninit::slice_get_ref(slice)
MaybeUninit::slice_assume_init_ref(slice)
}
}

Expand All @@ -82,7 +82,7 @@ impl<T, const N: usize> IntoIter<T, N> {
// SAFETY: We know that all elements within `alive` are properly initialized.
unsafe {
let slice = self.data.get_unchecked_mut(self.alive.clone());
MaybeUninit::slice_get_mut(slice)
MaybeUninit::slice_assume_init_mut(slice)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ impl<T, const N: usize> [T; N] {
}
let mut dst = MaybeUninit::uninit_array::<N>();
let mut guard: Guard<U, N> =
Guard { dst: MaybeUninit::first_ptr_mut(&mut dst), initialized: 0 };
Guard { dst: MaybeUninit::slice_as_mut_ptr(&mut dst), initialized: 0 };
for (src, dst) in IntoIter::new(self).zip(&mut dst) {
dst.write(f(src));
guard.initialized += 1;
Expand Down
11 changes: 7 additions & 4 deletions library/core/src/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ trait GenericRadix {
// SAFETY: The only chars in `buf` are created by `Self::digit` which are assumed to be
// valid UTF-8
let buf = unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(MaybeUninit::first_ptr(buf), buf.len()))
str::from_utf8_unchecked(slice::from_raw_parts(
MaybeUninit::slice_as_ptr(buf),
buf.len(),
))
};
f.pad_integral(is_nonnegative, Self::PREFIX, buf)
}
Expand Down Expand Up @@ -192,7 +195,7 @@ macro_rules! impl_Display {
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
let mut curr = buf.len() as isize;
let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();

// SAFETY: Since `d1` and `d2` are always less than or equal to `198`, we
Expand Down Expand Up @@ -322,7 +325,7 @@ macro_rules! impl_Exp {
// that `curr >= 0`.
let mut buf = [MaybeUninit::<u8>::uninit(); 40];
let mut curr = buf.len() as isize; //index for buf
let buf_ptr = MaybeUninit::first_ptr_mut(&mut buf);
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
let lut_ptr = DEC_DIGITS_LUT.as_ptr();

// decode 2 chars at a time
Expand Down Expand Up @@ -370,7 +373,7 @@ macro_rules! impl_Exp {

// stores 'e' (or 'E') and the up to 2-digit exponent
let mut exp_buf = [MaybeUninit::<u8>::uninit(); 3];
let exp_ptr = MaybeUninit::first_ptr_mut(&mut exp_buf);
let exp_ptr = MaybeUninit::slice_as_mut_ptr(&mut exp_buf);
// SAFETY: In either case, `exp_buf` is written within bounds and `exp_ptr[..len]`
// is contained within `exp_buf` since `len <= 3`.
let exp_slice = unsafe {
Expand Down
35 changes: 21 additions & 14 deletions library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ use crate::fmt;
use crate::intrinsics;
use crate::mem::ManuallyDrop;

// ignore-tidy-undocumented-unsafe

/// A wrapper type to construct uninitialized instances of `T`.
///
/// # Initialization invariant
Expand Down Expand Up @@ -281,7 +279,7 @@ impl<T> MaybeUninit<T> {
/// # Examples
///
/// ```no_run
/// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice_assume_init)]
/// #![feature(maybe_uninit_uninit_array, maybe_uninit_extra, maybe_uninit_slice)]
///
/// use std::mem::MaybeUninit;
///
Expand All @@ -293,7 +291,7 @@ impl<T> MaybeUninit<T> {
/// fn read(buf: &mut [MaybeUninit<u8>]) -> &[u8] {
/// unsafe {
/// let len = read_into_buffer(buf.as_mut_ptr() as *mut u8, buf.len());
/// MaybeUninit::slice_get_ref(&buf[..len])
/// MaybeUninit::slice_assume_init_ref(&buf[..len])
/// }
/// }
///
Expand All @@ -303,6 +301,7 @@ impl<T> MaybeUninit<T> {
#[unstable(feature = "maybe_uninit_uninit_array", issue = "none")]
#[inline(always)]
pub fn uninit_array<const LEN: usize>() -> [Self; LEN] {
// SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid.
unsafe { MaybeUninit::<[MaybeUninit<T>; LEN]>::uninit().assume_init() }
}

Expand Down Expand Up @@ -354,6 +353,7 @@ impl<T> MaybeUninit<T> {
#[rustc_diagnostic_item = "maybe_uninit_zeroed"]
pub fn zeroed() -> MaybeUninit<T> {
let mut u = MaybeUninit::<T>::uninit();
// SAFETY: `u.as_mut_ptr()` points to allocated memory.
unsafe {
u.as_mut_ptr().write_bytes(0u8, 1);
}
Expand All @@ -367,10 +367,9 @@ impl<T> MaybeUninit<T> {
#[unstable(feature = "maybe_uninit_extra", issue = "63567")]
#[inline(always)]
pub fn write(&mut self, val: T) -> &mut T {
unsafe {
self.value = ManuallyDrop::new(val);
self.assume_init_mut()
}
*self = MaybeUninit::new(val);
// SAFETY: We just initialized this value.
unsafe { self.assume_init_mut() }
}

/// Gets a pointer to the contained value. Reading from this pointer or turning it
Expand Down Expand Up @@ -769,9 +768,13 @@ impl<T> MaybeUninit<T> {
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
#[unstable(feature = "maybe_uninit_slice_assume_init", issue = "none")]
///
/// See [`assume_init_ref`] for more details and examples.
///
/// [`assume_init_ref`]: MaybeUninit::assume_init_ref
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub unsafe fn slice_get_ref(slice: &[Self]) -> &[T] {
pub unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
// SAFETY: casting slice to a `*const [T]` is safe since the caller guarantees that
// `slice` is initialized, and`MaybeUninit` is guaranteed to have the same layout as `T`.
// The pointer obtained is valid since it refers to memory owned by `slice` which is a
Expand All @@ -786,9 +789,13 @@ impl<T> MaybeUninit<T> {
/// It is up to the caller to guarantee that the `MaybeUninit<T>` elements
/// really are in an initialized state.
/// Calling this when the content is not yet fully initialized causes undefined behavior.
#[unstable(feature = "maybe_uninit_slice_assume_init", issue = "none")]
///
/// See [`assume_init_mut`] for more details and examples.
///
/// [`assume_init_mut`]: MaybeUninit::assume_init_mut
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub unsafe fn slice_get_mut(slice: &mut [Self]) -> &mut [T] {
pub unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
// SAFETY: similar to safety notes for `slice_get_ref`, but we have a
// mutable reference which is also guaranteed to be valid for writes.
unsafe { &mut *(slice as *mut [Self] as *mut [T]) }
Expand All @@ -797,14 +804,14 @@ impl<T> MaybeUninit<T> {
/// Gets a pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T {
pub fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
this as *const [MaybeUninit<T>] as *const T
}

/// Gets a mutable pointer to the first element of the array.
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
#[inline(always)]
pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T {
pub fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
this as *mut [MaybeUninit<T>] as *mut T
}
}
Loading

0 comments on commit cdc8f06

Please sign in to comment.