Add inherent versions of MaybeUninit methods for slices
This commit is contained in:
parent
12445e0b2c
commit
e37daf0c86
18 changed files with 543 additions and 441 deletions
|
@ -78,7 +78,7 @@ impl<T> ArenaChunk<T> {
|
|||
// been initialized.
|
||||
unsafe {
|
||||
let slice = self.storage.as_mut();
|
||||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
|
||||
slice[..len].assume_init_drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,9 +383,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
|
|||
/// Borrows a view into the keys stored in the node.
|
||||
pub fn keys(&self) -> &[K] {
|
||||
let leaf = self.into_leaf();
|
||||
unsafe {
|
||||
MaybeUninit::slice_assume_init_ref(leaf.keys.get_unchecked(..usize::from(leaf.len)))
|
||||
}
|
||||
unsafe { leaf.keys.get_unchecked(..usize::from(leaf.len)).assume_init_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,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_assume_init_ref(slice)
|
||||
slice.assume_init_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,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_assume_init_mut(slice)
|
||||
slice.assume_init_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
|
|||
// SAFETY: These elements are currently initialized, so it's fine to drop them.
|
||||
unsafe {
|
||||
let slice = self.data.get_unchecked_mut(range_to_drop);
|
||||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
|
||||
slice.assume_init_drop();
|
||||
}
|
||||
|
||||
NonZero::new(remaining).map_or(Ok(()), Err)
|
||||
|
@ -340,7 +340,7 @@ impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
|
|||
// SAFETY: These elements are currently initialized, so it's fine to drop them.
|
||||
unsafe {
|
||||
let slice = self.data.get_unchecked_mut(range_to_drop);
|
||||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice));
|
||||
slice.assume_init_drop();
|
||||
}
|
||||
|
||||
NonZero::new(remaining).map_or(Ok(()), Err)
|
||||
|
|
|
@ -911,9 +911,7 @@ impl<T> Drop for Guard<'_, T> {
|
|||
|
||||
// SAFETY: this slice will contain only initialized objects.
|
||||
unsafe {
|
||||
crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
|
||||
self.array_mut.get_unchecked_mut(..self.initialized),
|
||||
));
|
||||
self.array_mut.get_unchecked_mut(..self.initialized).assume_init_drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ impl<'data> BorrowedBuf<'data> {
|
|||
// SAFETY: We only slice the filled part of the buffer, which is always valid
|
||||
unsafe {
|
||||
let buf = self.buf.get_unchecked(..self.filled);
|
||||
MaybeUninit::slice_assume_init_ref(buf)
|
||||
buf.assume_init_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ impl<'data> BorrowedBuf<'data> {
|
|||
// SAFETY: We only slice the filled part of the buffer, which is always valid
|
||||
unsafe {
|
||||
let buf = self.buf.get_unchecked_mut(..self.filled);
|
||||
MaybeUninit::slice_assume_init_mut(buf)
|
||||
buf.assume_init_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ impl<'data> BorrowedBuf<'data> {
|
|||
// SAFETY: We only slice the filled part of the buffer, which is always valid
|
||||
unsafe {
|
||||
let buf = self.buf.get_unchecked(..self.filled);
|
||||
MaybeUninit::slice_assume_init_ref(buf)
|
||||
buf.assume_init_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ impl<'data> BorrowedBuf<'data> {
|
|||
// SAFETY: We only slice the filled part of the buffer, which is always valid
|
||||
unsafe {
|
||||
let buf = self.buf.get_unchecked_mut(..self.filled);
|
||||
MaybeUninit::slice_assume_init_mut(buf)
|
||||
buf.assume_init_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ impl<'a> BorrowedCursor<'a> {
|
|||
// SAFETY: We only slice the initialized part of the buffer, which is always valid
|
||||
unsafe {
|
||||
let buf = self.buf.buf.get_unchecked(self.buf.filled..self.buf.init);
|
||||
MaybeUninit::slice_assume_init_ref(buf)
|
||||
buf.assume_init_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +243,7 @@ impl<'a> BorrowedCursor<'a> {
|
|||
// SAFETY: We only slice the initialized part of the buffer, which is always valid
|
||||
unsafe {
|
||||
let buf = self.buf.buf.get_unchecked_mut(self.buf.filled..self.buf.init);
|
||||
MaybeUninit::slice_assume_init_mut(buf)
|
||||
buf.assume_init_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,7 +344,7 @@ impl<'a> BorrowedCursor<'a> {
|
|||
|
||||
// SAFETY: we do not de-initialize any of the elements of the slice
|
||||
unsafe {
|
||||
MaybeUninit::copy_from_slice(&mut self.as_mut()[..buf.len()], buf);
|
||||
self.as_mut()[..buf.len()].write_copy_of_slice(buf);
|
||||
}
|
||||
|
||||
// SAFETY: We just added the entire contents of buf to the filled section.
|
||||
|
|
|
@ -81,9 +81,7 @@ where
|
|||
if const { crate::mem::needs_drop::<T>() } {
|
||||
// SAFETY: self.initialized is always <= N, which also is the length of the array.
|
||||
unsafe {
|
||||
core::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
|
||||
self.array.get_unchecked_mut(..self.initialized),
|
||||
));
|
||||
self.array.get_unchecked_mut(..self.initialized).assume_init_drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::any::type_name;
|
||||
use crate::mem::{self, ManuallyDrop};
|
||||
use crate::mem::ManuallyDrop;
|
||||
use crate::{fmt, intrinsics, ptr, slice};
|
||||
|
||||
/// A wrapper type to construct uninitialized instances of `T`.
|
||||
|
@ -354,7 +354,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_assume_init_ref(&buf[..len])
|
||||
/// buf[..len].assume_init_ref()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
|
@ -740,7 +740,7 @@ impl<T> MaybeUninit<T> {
|
|||
///
|
||||
/// On top of that, all additional invariants of the type `T` must be
|
||||
/// satisfied, as the `Drop` implementation of `T` (or its members) may
|
||||
/// rely on this. For example, setting a [`Vec<T>`] to an invalid but
|
||||
/// rely on this. For example, setting a `Vec<T>` to an invalid but
|
||||
/// non-null address makes it initialized (under the current implementation;
|
||||
/// this does not constitute a stable guarantee), because the only
|
||||
/// requirement the compiler knows about it is that the data pointer must be
|
||||
|
@ -748,7 +748,6 @@ impl<T> MaybeUninit<T> {
|
|||
/// behavior.
|
||||
///
|
||||
/// [`assume_init`]: MaybeUninit::assume_init
|
||||
/// [`Vec<T>`]: ../../std/vec/struct.Vec.html
|
||||
#[stable(feature = "maybe_uninit_extra", since = "1.60.0")]
|
||||
pub unsafe fn assume_init_drop(&mut self) {
|
||||
// SAFETY: the caller must guarantee that `self` is initialized and
|
||||
|
@ -982,339 +981,6 @@ impl<T> MaybeUninit<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Assuming all the elements are initialized, get a slice to them.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// 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 const 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
|
||||
// reference and thus guaranteed to be valid for reads.
|
||||
unsafe { &*(slice as *const [Self] as *const [T]) }
|
||||
}
|
||||
|
||||
/// Assuming all the elements are initialized, get a mutable slice to them.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// 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 const 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]) }
|
||||
}
|
||||
|
||||
/// Gets a pointer to the first element of the array.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub const fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
|
||||
this.as_ptr() as *const T
|
||||
}
|
||||
|
||||
/// Gets a mutable pointer to the first element of the array.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub const fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
|
||||
this.as_mut_ptr() as *mut T
|
||||
}
|
||||
|
||||
/// Copies the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
|
||||
///
|
||||
/// If `T` does not implement `Copy`, use [`clone_from_slice`]
|
||||
///
|
||||
/// This is similar to [`slice::copy_from_slice`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the two slices have different lengths.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut dst = [MaybeUninit::uninit(); 32];
|
||||
/// let src = [0; 32];
|
||||
///
|
||||
/// let init = MaybeUninit::copy_from_slice(&mut dst, &src);
|
||||
///
|
||||
/// assert_eq!(init, src);
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut vec = Vec::with_capacity(32);
|
||||
/// let src = [0; 16];
|
||||
///
|
||||
/// MaybeUninit::copy_from_slice(&mut vec.spare_capacity_mut()[..src.len()], &src);
|
||||
///
|
||||
/// // SAFETY: we have just copied all the elements of len into the spare capacity
|
||||
/// // the first src.len() elements of the vec are valid now.
|
||||
/// unsafe {
|
||||
/// vec.set_len(src.len());
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(vec, src);
|
||||
/// ```
|
||||
///
|
||||
/// [`clone_from_slice`]: MaybeUninit::clone_from_slice
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
pub fn copy_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
// SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
|
||||
let uninit_src: &[MaybeUninit<T>] = unsafe { super::transmute(src) };
|
||||
|
||||
this.copy_from_slice(uninit_src);
|
||||
|
||||
// SAFETY: Valid elements have just been copied into `this` so it is initialized
|
||||
unsafe { MaybeUninit::slice_assume_init_mut(this) }
|
||||
}
|
||||
|
||||
/// Clones the elements from `src` to `this`, returning a mutable reference to the now initialized contents of `this`.
|
||||
/// Any already initialized elements will not be dropped.
|
||||
///
|
||||
/// If `T` implements `Copy`, use [`copy_from_slice`]
|
||||
///
|
||||
/// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics.
|
||||
///
|
||||
/// If there is a panic, the already cloned elements will be dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut dst = [MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit(), MaybeUninit::uninit()];
|
||||
/// let src = ["wibbly".to_string(), "wobbly".to_string(), "timey".to_string(), "wimey".to_string(), "stuff".to_string()];
|
||||
///
|
||||
/// let init = MaybeUninit::clone_from_slice(&mut dst, &src);
|
||||
///
|
||||
/// assert_eq!(init, src);
|
||||
/// # // Prevent leaks for Miri
|
||||
/// # unsafe { std::ptr::drop_in_place(init); }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut vec = Vec::with_capacity(32);
|
||||
/// let src = ["rust", "is", "a", "pretty", "cool", "language"];
|
||||
///
|
||||
/// MaybeUninit::clone_from_slice(&mut vec.spare_capacity_mut()[..src.len()], &src);
|
||||
///
|
||||
/// // SAFETY: we have just cloned all the elements of len into the spare capacity
|
||||
/// // the first src.len() elements of the vec are valid now.
|
||||
/// unsafe {
|
||||
/// vec.set_len(src.len());
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(vec, src);
|
||||
/// ```
|
||||
///
|
||||
/// [`copy_from_slice`]: MaybeUninit::copy_from_slice
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
pub fn clone_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
// unlike copy_from_slice this does not call clone_from_slice on the slice
|
||||
// this is because `MaybeUninit<T: Clone>` does not implement Clone.
|
||||
|
||||
assert_eq!(this.len(), src.len(), "destination and source slices have different lengths");
|
||||
// NOTE: We need to explicitly slice them to the same length
|
||||
// for bounds checking to be elided, and the optimizer will
|
||||
// generate memcpy for simple cases (for example T = u8).
|
||||
let len = this.len();
|
||||
let src = &src[..len];
|
||||
|
||||
// guard is needed b/c panic might happen during a clone
|
||||
let mut guard = Guard { slice: this, initialized: 0 };
|
||||
|
||||
for i in 0..len {
|
||||
guard.slice[i].write(src[i].clone());
|
||||
guard.initialized += 1;
|
||||
}
|
||||
|
||||
super::forget(guard);
|
||||
|
||||
// SAFETY: Valid elements have just been written into `this` so it is initialized
|
||||
unsafe { MaybeUninit::slice_assume_init_mut(this) }
|
||||
}
|
||||
|
||||
/// Fills `this` with elements by cloning `value`, returning a mutable reference to the now
|
||||
/// initialized contents of `this`.
|
||||
/// Any previously initialized elements will not be dropped.
|
||||
///
|
||||
/// This is similar to [`slice::fill`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if any call to `Clone` panics.
|
||||
///
|
||||
/// If such a panic occurs, any elements previously initialized during this operation will be
|
||||
/// dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Fill an uninit vec with 1.
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = vec![MaybeUninit::uninit(); 10];
|
||||
/// let initialized = MaybeUninit::fill(buf.as_mut_slice(), 1);
|
||||
/// assert_eq!(initialized, &mut [1; 10]);
|
||||
/// ```
|
||||
#[doc(alias = "memset")]
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
pub fn fill<'a>(this: &'a mut [MaybeUninit<T>], value: T) -> &'a mut [T]
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
SpecFill::spec_fill(this, value);
|
||||
// SAFETY: Valid elements have just been filled into `this` so it is initialized
|
||||
unsafe { MaybeUninit::slice_assume_init_mut(this) }
|
||||
}
|
||||
|
||||
/// Fills `this` with elements returned by calling a closure repeatedly.
|
||||
///
|
||||
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
|
||||
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
|
||||
/// pass [`Default::default`] as the argument.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if any call to the provided closure panics.
|
||||
///
|
||||
/// If such a panic occurs, any elements previously initialized during this operation will be
|
||||
/// dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Fill an uninit vec with the default value.
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = vec![MaybeUninit::<i32>::uninit(); 10];
|
||||
/// let initialized = MaybeUninit::fill_with(buf.as_mut_slice(), Default::default);
|
||||
/// assert_eq!(initialized, &mut [0; 10]);
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
pub fn fill_with<'a, F>(this: &'a mut [MaybeUninit<T>], mut f: F) -> &'a mut [T]
|
||||
where
|
||||
F: FnMut() -> T,
|
||||
{
|
||||
let mut guard = Guard { slice: this, initialized: 0 };
|
||||
|
||||
for element in guard.slice.iter_mut() {
|
||||
element.write(f());
|
||||
guard.initialized += 1;
|
||||
}
|
||||
|
||||
super::forget(guard);
|
||||
|
||||
// SAFETY: Valid elements have just been written into `this` so it is initialized
|
||||
unsafe { MaybeUninit::slice_assume_init_mut(this) }
|
||||
}
|
||||
|
||||
/// Fills `this` with elements yielded by an iterator until either all elements have been
|
||||
/// initialized or the iterator is empty.
|
||||
///
|
||||
/// Returns two slices. The first slice contains the initialized portion of the original slice.
|
||||
/// The second slice is the still-uninitialized remainder of the original slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if the iterator's `next` function panics.
|
||||
///
|
||||
/// If such a panic occurs, any elements previously initialized during this operation will be
|
||||
/// dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Fill an uninit vec with a cycling iterator.
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = vec![MaybeUninit::uninit(); 5];
|
||||
///
|
||||
/// let iter = [1, 2, 3].into_iter().cycle();
|
||||
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
|
||||
///
|
||||
/// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
|
||||
/// assert_eq!(0, remainder.len());
|
||||
/// ```
|
||||
///
|
||||
/// Fill an uninit vec, but not completely.
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = vec![MaybeUninit::uninit(); 5];
|
||||
/// let iter = [1, 2];
|
||||
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
|
||||
///
|
||||
/// assert_eq!(initialized, &mut [1, 2]);
|
||||
/// assert_eq!(remainder.len(), 3);
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
pub fn fill_from<'a, I>(
|
||||
this: &'a mut [MaybeUninit<T>],
|
||||
it: I,
|
||||
) -> (&'a mut [T], &'a mut [MaybeUninit<T>])
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
let iter = it.into_iter();
|
||||
let mut guard = Guard { slice: this, initialized: 0 };
|
||||
|
||||
for (element, val) in guard.slice.iter_mut().zip(iter) {
|
||||
element.write(val);
|
||||
guard.initialized += 1;
|
||||
}
|
||||
|
||||
let initialized_len = guard.initialized;
|
||||
super::forget(guard);
|
||||
|
||||
// SAFETY: guard.initialized <= this.len()
|
||||
let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) };
|
||||
|
||||
// SAFETY: Valid elements have just been written into `init`, so that portion
|
||||
// of `this` is initialized.
|
||||
(unsafe { MaybeUninit::slice_assume_init_mut(initted) }, remainder)
|
||||
}
|
||||
|
||||
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
|
||||
///
|
||||
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
|
||||
|
@ -1329,14 +995,14 @@ impl<T> MaybeUninit<T> {
|
|||
/// let val = 0x12345678_i32;
|
||||
/// let uninit = MaybeUninit::new(val);
|
||||
/// let uninit_bytes = uninit.as_bytes();
|
||||
/// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(uninit_bytes) };
|
||||
/// let bytes = unsafe { uninit_bytes.assume_init_ref() };
|
||||
/// assert_eq!(bytes, val.to_ne_bytes());
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
pub fn as_bytes(&self) -> &[MaybeUninit<u8>] {
|
||||
pub const fn as_bytes(&self) -> &[MaybeUninit<u8>] {
|
||||
// SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
|
||||
unsafe {
|
||||
slice::from_raw_parts(self.as_ptr() as *const MaybeUninit<u8>, mem::size_of::<T>())
|
||||
slice::from_raw_parts(self.as_ptr().cast::<MaybeUninit<u8>>(), super::size_of::<T>())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1364,18 +1030,397 @@ impl<T> MaybeUninit<T> {
|
|||
/// assert_eq!(val2, 0x123456cd);
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
pub fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
pub const fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
// SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
self.as_mut_ptr() as *mut MaybeUninit<u8>,
|
||||
mem::size_of::<T>(),
|
||||
self.as_mut_ptr().cast::<MaybeUninit<u8>>(),
|
||||
super::size_of::<T>(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the contents of this slice of `MaybeUninit` as a slice of potentially uninitialized
|
||||
/// bytes.
|
||||
/// Deprecated version of [`slice::assume_init_ref`].
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent assume_init_ref method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub const unsafe fn slice_assume_init_ref(slice: &[Self]) -> &[T] {
|
||||
// SAFETY: Same for both methods.
|
||||
unsafe { slice.assume_init_ref() }
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::assume_init_mut`].
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[rustc_const_unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent assume_init_mut method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub const unsafe fn slice_assume_init_mut(slice: &mut [Self]) -> &mut [T] {
|
||||
// SAFETY: Same for both methods.
|
||||
unsafe { slice.assume_init_mut() }
|
||||
}
|
||||
|
||||
/// Gets a pointer to the first element of the array.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub const fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
|
||||
this.as_ptr() as *const T
|
||||
}
|
||||
|
||||
/// Gets a mutable pointer to the first element of the array.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub const fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
|
||||
this.as_mut_ptr() as *mut T
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::write_copy_of_slice`].
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent write_copy_of_slice method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn copy_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
this.write_copy_of_slice(src)
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::write_clone_of_slice`].
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent write_clone_of_slice method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn clone_from_slice<'a>(this: &'a mut [MaybeUninit<T>], src: &[T]) -> &'a mut [T]
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
this.write_clone_of_slice(src)
|
||||
}
|
||||
|
||||
/// Fills a slice with elements by cloning `value`, returning a mutable reference to the now
|
||||
/// initialized contents of the slice.
|
||||
/// Any previously initialized elements will not be dropped.
|
||||
///
|
||||
/// This is similar to [`slice::fill`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if any call to `Clone` panics.
|
||||
///
|
||||
/// If such a panic occurs, any elements previously initialized during this operation will be
|
||||
/// dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = [const { MaybeUninit::uninit() }; 10];
|
||||
/// let initialized = MaybeUninit::fill(&mut buf, 1);
|
||||
/// assert_eq!(initialized, &mut [1; 10]);
|
||||
/// ```
|
||||
#[doc(alias = "memset")]
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
pub fn fill(this: &mut [MaybeUninit<T>], value: T) -> &mut [T]
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
SpecFill::spec_fill(this, value);
|
||||
// SAFETY: Valid elements have just been filled into `this` so it is initialized
|
||||
unsafe { this.assume_init_mut() }
|
||||
}
|
||||
|
||||
/// Fills a slice with elements returned by calling a closure repeatedly.
|
||||
///
|
||||
/// This method uses a closure to create new values. If you'd rather `Clone` a given value, use
|
||||
/// [`MaybeUninit::fill`]. If you want to use the `Default` trait to generate values, you can
|
||||
/// pass [`Default::default`] as the argument.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if any call to the provided closure panics.
|
||||
///
|
||||
/// If such a panic occurs, any elements previously initialized during this operation will be
|
||||
/// dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = [const { MaybeUninit::<i32>::uninit() }; 10];
|
||||
/// let initialized = MaybeUninit::fill_with(&mut buf, Default::default);
|
||||
/// assert_eq!(initialized, &mut [0; 10]);
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
pub fn fill_with<F>(this: &mut [MaybeUninit<T>], mut f: F) -> &mut [T]
|
||||
where
|
||||
F: FnMut() -> T,
|
||||
{
|
||||
let mut guard = Guard { slice: this, initialized: 0 };
|
||||
|
||||
for element in guard.slice.iter_mut() {
|
||||
element.write(f());
|
||||
guard.initialized += 1;
|
||||
}
|
||||
|
||||
super::forget(guard);
|
||||
|
||||
// SAFETY: Valid elements have just been written into `this` so it is initialized
|
||||
unsafe { this.assume_init_mut() }
|
||||
}
|
||||
|
||||
/// Fills a slice with elements yielded by an iterator until either all elements have been
|
||||
/// initialized or the iterator is empty.
|
||||
///
|
||||
/// Returns two slices. The first slice contains the initialized portion of the original slice.
|
||||
/// The second slice is the still-uninitialized remainder of the original slice.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if the iterator's `next` function panics.
|
||||
///
|
||||
/// If such a panic occurs, any elements previously initialized during this operation will be
|
||||
/// dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Completely filling the slice:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
|
||||
///
|
||||
/// let iter = [1, 2, 3].into_iter().cycle();
|
||||
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
|
||||
///
|
||||
/// assert_eq!(initialized, &mut [1, 2, 3, 1, 2]);
|
||||
/// assert_eq!(remainder.len(), 0);
|
||||
/// ```
|
||||
///
|
||||
/// Partially filling the slice:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = [const { MaybeUninit::uninit() }; 5];
|
||||
/// let iter = [1, 2];
|
||||
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter);
|
||||
///
|
||||
/// assert_eq!(initialized, &mut [1, 2]);
|
||||
/// assert_eq!(remainder.len(), 3);
|
||||
/// ```
|
||||
///
|
||||
/// Checking an iterator after filling a slice:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_fill)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut buf = [const { MaybeUninit::uninit() }; 3];
|
||||
/// let mut iter = [1, 2, 3, 4, 5].into_iter();
|
||||
/// let (initialized, remainder) = MaybeUninit::fill_from(&mut buf, iter.by_ref());
|
||||
///
|
||||
/// assert_eq!(initialized, &mut [1, 2, 3]);
|
||||
/// assert_eq!(remainder.len(), 0);
|
||||
/// assert_eq!(iter.as_slice(), &[4, 5]);
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_fill", issue = "117428")]
|
||||
pub fn fill_from<I>(this: &mut [MaybeUninit<T>], it: I) -> (&mut [T], &mut [MaybeUninit<T>])
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
let iter = it.into_iter();
|
||||
let mut guard = Guard { slice: this, initialized: 0 };
|
||||
|
||||
for (element, val) in guard.slice.iter_mut().zip(iter) {
|
||||
element.write(val);
|
||||
guard.initialized += 1;
|
||||
}
|
||||
|
||||
let initialized_len = guard.initialized;
|
||||
super::forget(guard);
|
||||
|
||||
// SAFETY: guard.initialized <= this.len()
|
||||
let (initted, remainder) = unsafe { this.split_at_mut_unchecked(initialized_len) };
|
||||
|
||||
// SAFETY: Valid elements have just been written into `init`, so that portion
|
||||
// of `this` is initialized.
|
||||
(unsafe { initted.assume_init_mut() }, remainder)
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::as_bytes`].
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent as_bytes method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn slice_as_bytes(this: &[MaybeUninit<T>]) -> &[MaybeUninit<u8>] {
|
||||
this.as_bytes()
|
||||
}
|
||||
|
||||
/// Deprecated version of [`slice::as_bytes_mut`].
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
#[deprecated(
|
||||
note = "replaced by inherent as_bytes_mut method; will eventually be removed",
|
||||
since = "1.83.0"
|
||||
)]
|
||||
pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>] {
|
||||
this.as_bytes_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> [MaybeUninit<T>] {
|
||||
/// Copies the elements from `src` to `self`,
|
||||
/// returning a mutable reference to the now initialized contents of `self`.
|
||||
///
|
||||
/// If `T` does not implement `Copy`, use [`write_clone_of_slice`] instead.
|
||||
///
|
||||
/// This is similar to [`slice::copy_from_slice`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the two slices have different lengths.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut dst = [MaybeUninit::uninit(); 32];
|
||||
/// let src = [0; 32];
|
||||
///
|
||||
/// let init = dst.write_copy_of_slice(&src);
|
||||
///
|
||||
/// assert_eq!(init, src);
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
///
|
||||
/// let mut vec = Vec::with_capacity(32);
|
||||
/// let src = [0; 16];
|
||||
///
|
||||
/// vec.spare_capacity_mut()[..src.len()].write_copy_of_slice(&src);
|
||||
///
|
||||
/// // SAFETY: we have just copied all the elements of len into the spare capacity
|
||||
/// // the first src.len() elements of the vec are valid now.
|
||||
/// unsafe {
|
||||
/// vec.set_len(src.len());
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(vec, src);
|
||||
/// ```
|
||||
///
|
||||
/// [`write_clone_of_slice`]: slice::write_clone_of_slice
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
#[rustc_const_unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
pub const fn write_copy_of_slice(&mut self, src: &[T]) -> &mut [T]
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
// SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
|
||||
let uninit_src: &[MaybeUninit<T>] = unsafe { super::transmute(src) };
|
||||
|
||||
self.copy_from_slice(uninit_src);
|
||||
|
||||
// SAFETY: Valid elements have just been copied into `self` so it is initialized
|
||||
unsafe { self.assume_init_mut() }
|
||||
}
|
||||
|
||||
/// Clones the elements from `src` to `self`,
|
||||
/// returning a mutable reference to the now initialized contents of `self`.
|
||||
/// Any already initialized elements will not be dropped.
|
||||
///
|
||||
/// If `T` implements `Copy`, use [`write_copy_of_slice`] instead.
|
||||
///
|
||||
/// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics.
|
||||
///
|
||||
/// If there is a panic, the already cloned elements will be dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let mut dst = [const { MaybeUninit::uninit() }; 5];
|
||||
/// let src = ["wibbly", "wobbly", "timey", "wimey", "stuff"].map(|s| s.to_string());
|
||||
///
|
||||
/// let init = dst.write_clone_of_slice(&src);
|
||||
///
|
||||
/// assert_eq!(init, src);
|
||||
///
|
||||
/// # // Prevent leaks for Miri
|
||||
/// # unsafe { std::ptr::drop_in_place(init); }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(maybe_uninit_write_slice)]
|
||||
///
|
||||
/// let mut vec = Vec::with_capacity(32);
|
||||
/// let src = ["rust", "is", "a", "pretty", "cool", "language"].map(|s| s.to_string());
|
||||
///
|
||||
/// vec.spare_capacity_mut()[..src.len()].write_clone_of_slice(&src);
|
||||
///
|
||||
/// // SAFETY: we have just cloned all the elements of len into the spare capacity
|
||||
/// // the first src.len() elements of the vec are valid now.
|
||||
/// unsafe {
|
||||
/// vec.set_len(src.len());
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(vec, src);
|
||||
/// ```
|
||||
///
|
||||
/// [`write_copy_of_slice`]: slice::write_copy_of_slice
|
||||
#[unstable(feature = "maybe_uninit_write_slice", issue = "79995")]
|
||||
pub fn write_clone_of_slice(&mut self, src: &[T]) -> &mut [T]
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
// unlike copy_from_slice this does not call clone_from_slice on the slice
|
||||
// this is because `MaybeUninit<T: Clone>` does not implement Clone.
|
||||
|
||||
assert_eq!(self.len(), src.len(), "destination and source slices have different lengths");
|
||||
|
||||
// NOTE: We need to explicitly slice them to the same length
|
||||
// for bounds checking to be elided, and the optimizer will
|
||||
// generate memcpy for simple cases (for example T = u8).
|
||||
let len = self.len();
|
||||
let src = &src[..len];
|
||||
|
||||
// guard is needed b/c panic might happen during a clone
|
||||
let mut guard = Guard { slice: self, initialized: 0 };
|
||||
|
||||
for i in 0..len {
|
||||
guard.slice[i].write(src[i].clone());
|
||||
guard.initialized += 1;
|
||||
}
|
||||
|
||||
super::forget(guard);
|
||||
|
||||
// SAFETY: Valid elements have just been written into `self` so it is initialized
|
||||
unsafe { self.assume_init_mut() }
|
||||
}
|
||||
|
||||
/// Returns the contents of this `MaybeUninit` as a slice of potentially uninitialized bytes.
|
||||
///
|
||||
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
|
||||
/// contain padding bytes which are left uninitialized.
|
||||
|
@ -1387,21 +1432,22 @@ impl<T> MaybeUninit<T> {
|
|||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// let uninit = [MaybeUninit::new(0x1234u16), MaybeUninit::new(0x5678u16)];
|
||||
/// let uninit_bytes = MaybeUninit::slice_as_bytes(&uninit);
|
||||
/// let bytes = unsafe { MaybeUninit::slice_assume_init_ref(&uninit_bytes) };
|
||||
/// let uninit_bytes = uninit.as_bytes();
|
||||
/// let bytes = unsafe { uninit_bytes.assume_init_ref() };
|
||||
/// let val1 = u16::from_ne_bytes(bytes[0..2].try_into().unwrap());
|
||||
/// let val2 = u16::from_ne_bytes(bytes[2..4].try_into().unwrap());
|
||||
/// assert_eq!(&[val1, val2], &[0x1234u16, 0x5678u16]);
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
pub fn slice_as_bytes(this: &[MaybeUninit<T>]) -> &[MaybeUninit<u8>] {
|
||||
let bytes = mem::size_of_val(this);
|
||||
pub const fn as_bytes(&self) -> &[MaybeUninit<u8>] {
|
||||
// SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
|
||||
unsafe { slice::from_raw_parts(this.as_ptr() as *const MaybeUninit<u8>, bytes) }
|
||||
unsafe {
|
||||
slice::from_raw_parts(self.as_ptr().cast::<MaybeUninit<u8>>(), super::size_of_val(self))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the contents of this mutable slice of `MaybeUninit` as a mutable slice of
|
||||
/// potentially uninitialized bytes.
|
||||
/// Returns the contents of this `MaybeUninit` slice as a mutable slice of potentially
|
||||
/// uninitialized bytes.
|
||||
///
|
||||
/// Note that even if the contents of a `MaybeUninit` have been initialized, the value may still
|
||||
/// contain padding bytes which are left uninitialized.
|
||||
|
@ -1414,8 +1460,8 @@ impl<T> MaybeUninit<T> {
|
|||
///
|
||||
/// let mut uninit = [MaybeUninit::<u16>::uninit(), MaybeUninit::<u16>::uninit()];
|
||||
/// let uninit_bytes = MaybeUninit::slice_as_bytes_mut(&mut uninit);
|
||||
/// MaybeUninit::copy_from_slice(uninit_bytes, &[0x12, 0x34, 0x56, 0x78]);
|
||||
/// let vals = unsafe { MaybeUninit::slice_assume_init_ref(&uninit) };
|
||||
/// uninit_bytes.write_copy_of_slice(&[0x12, 0x34, 0x56, 0x78]);
|
||||
/// let vals = unsafe { uninit.assume_init_ref() };
|
||||
/// if cfg!(target_endian = "little") {
|
||||
/// assert_eq!(vals, &[0x3412u16, 0x7856u16]);
|
||||
/// } else {
|
||||
|
@ -1423,10 +1469,74 @@ impl<T> MaybeUninit<T> {
|
|||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")]
|
||||
pub fn slice_as_bytes_mut(this: &mut [MaybeUninit<T>]) -> &mut [MaybeUninit<u8>] {
|
||||
let bytes = mem::size_of_val(this);
|
||||
pub const fn as_bytes_mut(&mut self) -> &mut [MaybeUninit<u8>] {
|
||||
// SAFETY: MaybeUninit<u8> is always valid, even for padding bytes
|
||||
unsafe { slice::from_raw_parts_mut(this.as_mut_ptr() as *mut MaybeUninit<u8>, bytes) }
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(
|
||||
self.as_mut_ptr() as *mut MaybeUninit<u8>,
|
||||
super::size_of_val(self),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Drops the contained values in place.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// It is up to the caller to guarantee that every `MaybeUninit<T>` in the slice
|
||||
/// really is in an initialized state. Calling this when the content is not yet
|
||||
/// fully initialized causes undefined behavior.
|
||||
///
|
||||
/// On top of that, all additional invariants of the type `T` must be
|
||||
/// satisfied, as the `Drop` implementation of `T` (or its members) may
|
||||
/// rely on this. For example, setting a `Vec<T>` to an invalid but
|
||||
/// non-null address makes it initialized (under the current implementation;
|
||||
/// this does not constitute a stable guarantee), because the only
|
||||
/// requirement the compiler knows about it is that the data pointer must be
|
||||
/// non-null. Dropping such a `Vec<T>` however will cause undefined
|
||||
/// behaviour.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn assume_init_drop(&mut self) {
|
||||
if !self.is_empty() {
|
||||
// SAFETY: the caller must guarantee that every element of `self`
|
||||
// is initialized and satisfies all invariants of `T`.
|
||||
// Dropping the value in place is safe if that is the case.
|
||||
unsafe { ptr::drop_in_place(self as *mut [MaybeUninit<T>] as *mut [T]) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a shared reference to the contained value.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Calling this when the content is not yet fully initialized causes undefined
|
||||
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
|
||||
/// the slice really is in an initialized state.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub const unsafe fn assume_init_ref(&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
|
||||
// reference and thus guaranteed to be valid for reads.
|
||||
unsafe { &*(self as *const Self as *const [T]) }
|
||||
}
|
||||
|
||||
/// Gets a mutable (unique) reference to the contained value.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Calling this when the content is not yet fully initialized causes undefined
|
||||
/// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
|
||||
/// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot
|
||||
/// be used to initialize a `MaybeUninit` slice.
|
||||
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
|
||||
#[inline(always)]
|
||||
pub const unsafe fn assume_init_mut(&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 *(self as *mut Self as *mut [T]) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1479,7 +1589,7 @@ impl<'a, T> Drop for Guard<'a, T> {
|
|||
let initialized_part = &mut self.slice[..self.initialized];
|
||||
// SAFETY: this raw sub-slice will contain only initialized objects.
|
||||
unsafe {
|
||||
crate::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(initialized_part));
|
||||
initialized_part.assume_init_drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ impl<const SIZE: usize> DisplayBuffer<SIZE> {
|
|||
// SAFETY: `buf` is only written to by the `fmt::Write::write_str` implementation
|
||||
// which writes a valid UTF-8 string to `buf` and correctly sets `len`.
|
||||
unsafe {
|
||||
let s = MaybeUninit::slice_assume_init_ref(&self.buf[..self.len]);
|
||||
let s = self.buf[..self.len].assume_init_ref();
|
||||
str::from_utf8_unchecked(s)
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ impl<const SIZE: usize> fmt::Write for DisplayBuffer<SIZE> {
|
|||
let bytes = s.as_bytes();
|
||||
|
||||
if let Some(buf) = self.buf.get_mut(self.len..(self.len + bytes.len())) {
|
||||
MaybeUninit::copy_from_slice(buf, bytes);
|
||||
buf.write_copy_of_slice(bytes);
|
||||
self.len += bytes.len();
|
||||
Ok(())
|
||||
} else {
|
||||
|
|
|
@ -210,10 +210,10 @@ fn digits_to_dec_str<'a>(
|
|||
if frac_digits > buf.len() && frac_digits - buf.len() > minus_exp {
|
||||
parts[3] = MaybeUninit::new(Part::Zero((frac_digits - buf.len()) - minus_exp));
|
||||
// SAFETY: we just initialized the elements `..4`.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
|
||||
unsafe { parts[..4].assume_init_ref() }
|
||||
} else {
|
||||
// SAFETY: we just initialized the elements `..3`.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) }
|
||||
unsafe { parts[..3].assume_init_ref() }
|
||||
}
|
||||
} else {
|
||||
let exp = exp as usize;
|
||||
|
@ -225,10 +225,10 @@ fn digits_to_dec_str<'a>(
|
|||
if frac_digits > buf.len() - exp {
|
||||
parts[3] = MaybeUninit::new(Part::Zero(frac_digits - (buf.len() - exp)));
|
||||
// SAFETY: we just initialized the elements `..4`.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
|
||||
unsafe { parts[..4].assume_init_ref() }
|
||||
} else {
|
||||
// SAFETY: we just initialized the elements `..3`.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) }
|
||||
unsafe { parts[..3].assume_init_ref() }
|
||||
}
|
||||
} else {
|
||||
// the decimal point is after rendered digits: [1234][____0000] or [1234][__][.][__].
|
||||
|
@ -238,10 +238,10 @@ fn digits_to_dec_str<'a>(
|
|||
parts[2] = MaybeUninit::new(Part::Copy(b"."));
|
||||
parts[3] = MaybeUninit::new(Part::Zero(frac_digits));
|
||||
// SAFETY: we just initialized the elements `..4`.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..4]) }
|
||||
unsafe { parts[..4].assume_init_ref() }
|
||||
} else {
|
||||
// SAFETY: we just initialized the elements `..2`.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) }
|
||||
unsafe { parts[..2].assume_init_ref() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ fn digits_to_exp_str<'a>(
|
|||
parts[n + 1] = MaybeUninit::new(Part::Num(exp as u16));
|
||||
}
|
||||
// SAFETY: we just initialized the elements `..n + 2`.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&parts[..n + 2]) }
|
||||
unsafe { parts[..n + 2].assume_init_ref() }
|
||||
}
|
||||
|
||||
/// Sign formatting options.
|
||||
|
@ -366,12 +366,12 @@ where
|
|||
FullDecoded::Nan => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Infinite => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Zero => {
|
||||
if frac_digits > 0 {
|
||||
|
@ -381,14 +381,14 @@ where
|
|||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..2`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
|
||||
parts: unsafe { parts[..2].assume_init_ref() },
|
||||
}
|
||||
} else {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"0"));
|
||||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
|
||||
parts: unsafe { parts[..1].assume_init_ref() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -442,12 +442,12 @@ where
|
|||
FullDecoded::Nan => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Infinite => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Zero => {
|
||||
parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 {
|
||||
|
@ -456,7 +456,7 @@ where
|
|||
MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }))
|
||||
};
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Finite(ref decoded) => {
|
||||
let (buf, exp) = format_shortest(decoded, buf);
|
||||
|
@ -533,12 +533,12 @@ where
|
|||
FullDecoded::Nan => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Infinite => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Zero => {
|
||||
if ndigits > 1 {
|
||||
|
@ -549,14 +549,14 @@ where
|
|||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..3`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..3]) },
|
||||
parts: unsafe { parts[..3].assume_init_ref() },
|
||||
}
|
||||
} else {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(if upper { b"0E0" } else { b"0e0" }));
|
||||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
|
||||
parts: unsafe { parts[..1].assume_init_ref() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -607,12 +607,12 @@ where
|
|||
FullDecoded::Nan => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"NaN"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Infinite => {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"inf"));
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
Formatted { sign, parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) } }
|
||||
Formatted { sign, parts: unsafe { parts[..1].assume_init_ref() } }
|
||||
}
|
||||
FullDecoded::Zero => {
|
||||
if frac_digits > 0 {
|
||||
|
@ -622,14 +622,14 @@ where
|
|||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..2`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
|
||||
parts: unsafe { parts[..2].assume_init_ref() },
|
||||
}
|
||||
} else {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"0"));
|
||||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
|
||||
parts: unsafe { parts[..1].assume_init_ref() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -654,14 +654,14 @@ where
|
|||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..2`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..2]) },
|
||||
parts: unsafe { parts[..2].assume_init_ref() },
|
||||
}
|
||||
} else {
|
||||
parts[0] = MaybeUninit::new(Part::Copy(b"0"));
|
||||
Formatted {
|
||||
sign,
|
||||
// SAFETY: we just initialized the elements `..1`.
|
||||
parts: unsafe { MaybeUninit::slice_assume_init_ref(&parts[..1]) },
|
||||
parts: unsafe { parts[..1].assume_init_ref() },
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -247,7 +247,7 @@ pub fn format_shortest<'a>(
|
|||
// it seems that this condition is very hard to satisfy (possibly impossible),
|
||||
// but we are just being safe and consistent here.
|
||||
// SAFETY: we initialized that memory above.
|
||||
if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) }) {
|
||||
if let Some(c) = round_up(unsafe { buf[..i].assume_init_mut() }) {
|
||||
buf[i] = MaybeUninit::new(c);
|
||||
i += 1;
|
||||
k += 1;
|
||||
|
@ -255,7 +255,7 @@ pub fn format_shortest<'a>(
|
|||
}
|
||||
|
||||
// SAFETY: we initialized that memory above.
|
||||
(unsafe { MaybeUninit::slice_assume_init_ref(&buf[..i]) }, k)
|
||||
(unsafe { buf[..i].assume_init_ref() }, k)
|
||||
}
|
||||
|
||||
/// The exact and fixed mode implementation for Dragon.
|
||||
|
@ -333,7 +333,7 @@ pub fn format_exact<'a>(
|
|||
*c = MaybeUninit::new(b'0');
|
||||
}
|
||||
// SAFETY: we initialized that memory above.
|
||||
return (unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k);
|
||||
return (unsafe { buf[..len].assume_init_ref() }, k);
|
||||
}
|
||||
|
||||
let mut d = 0;
|
||||
|
@ -372,7 +372,7 @@ pub fn format_exact<'a>(
|
|||
// if rounding up changes the length, the exponent should also change.
|
||||
// but we've been requested a fixed number of digits, so do not alter the buffer...
|
||||
// SAFETY: we initialized that memory above.
|
||||
if let Some(c) = round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) }) {
|
||||
if let Some(c) = round_up(unsafe { buf[..len].assume_init_mut() }) {
|
||||
// ...unless we've been requested the fixed precision instead.
|
||||
// we also need to check that, if the original buffer was empty,
|
||||
// the additional digit can only be added when `k == limit` (edge case).
|
||||
|
@ -385,5 +385,5 @@ pub fn format_exact<'a>(
|
|||
}
|
||||
|
||||
// SAFETY: we initialized that memory above.
|
||||
(unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, k)
|
||||
(unsafe { buf[..len].assume_init_ref() }, k)
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ pub fn format_shortest_opt<'a>(
|
|||
let ten_kappa = (ten_kappa as u64) << e; // scale 10^kappa back to the shared exponent
|
||||
return round_and_weed(
|
||||
// SAFETY: we initialized that memory above.
|
||||
unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) },
|
||||
unsafe { buf[..i].assume_init_mut() },
|
||||
exp,
|
||||
plus1rem,
|
||||
delta1,
|
||||
|
@ -324,7 +324,7 @@ pub fn format_shortest_opt<'a>(
|
|||
let ten_kappa = 1 << e; // implicit divisor
|
||||
return round_and_weed(
|
||||
// SAFETY: we initialized that memory above.
|
||||
unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..i]) },
|
||||
unsafe { buf[..i].assume_init_mut() },
|
||||
exp,
|
||||
r,
|
||||
threshold,
|
||||
|
@ -713,7 +713,7 @@ pub fn format_exact_opt<'a>(
|
|||
// `10^kappa` did not overflow after all, the second check is fine.
|
||||
if ten_kappa - remainder > remainder && ten_kappa - 2 * remainder >= 2 * ulp {
|
||||
// SAFETY: our caller initialized that memory.
|
||||
return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp));
|
||||
return Some((unsafe { buf[..len].assume_init_ref() }, exp));
|
||||
}
|
||||
|
||||
// :<------- remainder ------>| :
|
||||
|
@ -736,7 +736,7 @@ pub fn format_exact_opt<'a>(
|
|||
if remainder > ulp && ten_kappa - (remainder - ulp) <= remainder - ulp {
|
||||
if let Some(c) =
|
||||
// SAFETY: our caller must have initialized that memory.
|
||||
round_up(unsafe { MaybeUninit::slice_assume_init_mut(&mut buf[..len]) })
|
||||
round_up(unsafe { buf[..len].assume_init_mut() })
|
||||
{
|
||||
// only add an additional digit when we've been requested the fixed precision.
|
||||
// we also need to check that, if the original buffer was empty,
|
||||
|
@ -748,7 +748,7 @@ pub fn format_exact_opt<'a>(
|
|||
}
|
||||
}
|
||||
// SAFETY: we and our caller initialized that memory.
|
||||
return Some((unsafe { MaybeUninit::slice_assume_init_ref(&buf[..len]) }, exp));
|
||||
return Some((unsafe { buf[..len].assume_init_ref() }, exp));
|
||||
}
|
||||
|
||||
// otherwise we are doomed (i.e., some values between `v - 1 ulp` and `v + 1 ulp` are
|
||||
|
|
|
@ -200,60 +200,60 @@ fn uninit_array_assume_init() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn uninit_write_slice() {
|
||||
fn uninit_write_copy_of_slice() {
|
||||
let mut dst = [MaybeUninit::new(255); 64];
|
||||
let src = [0; 64];
|
||||
|
||||
assert_eq!(MaybeUninit::copy_from_slice(&mut dst, &src), &src);
|
||||
assert_eq!(dst.write_copy_of_slice(&src), &src);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "source slice length (32) does not match destination slice length (64)")]
|
||||
fn uninit_write_slice_panic_lt() {
|
||||
fn uninit_write_copy_of_slice_panic_lt() {
|
||||
let mut dst = [MaybeUninit::uninit(); 64];
|
||||
let src = [0; 32];
|
||||
|
||||
MaybeUninit::copy_from_slice(&mut dst, &src);
|
||||
dst.write_copy_of_slice(&src);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "source slice length (128) does not match destination slice length (64)")]
|
||||
fn uninit_write_slice_panic_gt() {
|
||||
fn uninit_write_copy_of_slice_panic_gt() {
|
||||
let mut dst = [MaybeUninit::uninit(); 64];
|
||||
let src = [0; 128];
|
||||
|
||||
MaybeUninit::copy_from_slice(&mut dst, &src);
|
||||
dst.write_copy_of_slice(&src);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uninit_clone_from_slice() {
|
||||
fn uninit_write_clone_of_slice() {
|
||||
let mut dst = [MaybeUninit::new(255); 64];
|
||||
let src = [0; 64];
|
||||
|
||||
assert_eq!(MaybeUninit::clone_from_slice(&mut dst, &src), &src);
|
||||
assert_eq!(dst.write_clone_of_slice(&src), &src);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "destination and source slices have different lengths")]
|
||||
fn uninit_write_slice_cloned_panic_lt() {
|
||||
fn uninit_write_clone_of_slice_panic_lt() {
|
||||
let mut dst = [MaybeUninit::uninit(); 64];
|
||||
let src = [0; 32];
|
||||
|
||||
MaybeUninit::clone_from_slice(&mut dst, &src);
|
||||
dst.write_clone_of_slice(&src);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "destination and source slices have different lengths")]
|
||||
fn uninit_write_slice_cloned_panic_gt() {
|
||||
fn uninit_write_clone_of_slice_panic_gt() {
|
||||
let mut dst = [MaybeUninit::uninit(); 64];
|
||||
let src = [0; 128];
|
||||
|
||||
MaybeUninit::clone_from_slice(&mut dst, &src);
|
||||
dst.write_clone_of_slice(&src);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(panic = "unwind")]
|
||||
fn uninit_write_slice_cloned_mid_panic() {
|
||||
fn uninit_write_clone_of_slice_mid_panic() {
|
||||
use std::panic;
|
||||
|
||||
enum IncrementOrPanic {
|
||||
|
@ -289,7 +289,7 @@ fn uninit_write_slice_cloned_mid_panic() {
|
|||
];
|
||||
|
||||
let err = panic::catch_unwind(panic::AssertUnwindSafe(|| {
|
||||
MaybeUninit::clone_from_slice(&mut dst, &src);
|
||||
dst.write_clone_of_slice(&src);
|
||||
}));
|
||||
|
||||
drop(src);
|
||||
|
@ -317,11 +317,11 @@ impl Drop for Bomb {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn uninit_write_slice_cloned_no_drop() {
|
||||
fn uninit_write_clone_of_slice_no_drop() {
|
||||
let mut dst = [MaybeUninit::uninit()];
|
||||
let src = [Bomb];
|
||||
|
||||
MaybeUninit::clone_from_slice(&mut dst, &src);
|
||||
dst.write_clone_of_slice(&src);
|
||||
|
||||
forget(src);
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ impl Arena {
|
|||
#[allow(clippy::mut_from_ref)] // arena allocator
|
||||
pub(crate) fn alloc_str<'a>(&'a self, string: &str) -> &'a mut str {
|
||||
let alloc = self.alloc_raw(string.len());
|
||||
let bytes = MaybeUninit::copy_from_slice(alloc, string.as_bytes());
|
||||
let bytes = alloc.write_copy_of_slice(string.as_bytes());
|
||||
|
||||
// SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena,
|
||||
// and immediately convert the clone back to `&str`.
|
||||
|
|
|
@ -295,7 +295,7 @@ fn clone_to_uninit() {
|
|||
|
||||
let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<OsStr>(a)];
|
||||
unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) };
|
||||
assert_eq!(a.as_encoded_bytes(), unsafe { MaybeUninit::slice_assume_init_ref(&storage) });
|
||||
assert_eq!(a.as_encoded_bytes(), unsafe { storage.assume_init_ref() });
|
||||
|
||||
let mut b: Box<OsStr> = OsStr::new("world.exe").into();
|
||||
assert_eq!(size_of_val::<OsStr>(a), size_of_val::<OsStr>(&b));
|
||||
|
|
|
@ -50,7 +50,7 @@ impl Buffer {
|
|||
pub fn buffer(&self) -> &[u8] {
|
||||
// SAFETY: self.pos and self.cap are valid, and self.cap => self.pos, and
|
||||
// that region is initialized because those are all invariants of this type.
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(self.buf.get_unchecked(self.pos..self.filled)) }
|
||||
unsafe { self.buf.get_unchecked(self.pos..self.filled).assume_init_ref() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -2069,9 +2069,7 @@ fn clone_to_uninit() {
|
|||
|
||||
let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<Path>(a)];
|
||||
unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) };
|
||||
assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe {
|
||||
MaybeUninit::slice_assume_init_ref(&storage)
|
||||
});
|
||||
assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe { storage.assume_init_ref() });
|
||||
|
||||
let mut b: Box<Path> = Path::new("world.exe").into();
|
||||
assert_eq!(size_of_val::<Path>(a), size_of_val::<Path>(&b));
|
||||
|
|
|
@ -272,7 +272,7 @@ where
|
|||
unreachable!();
|
||||
} else {
|
||||
// Safety: First `k` values are initialized.
|
||||
let slice: &[u16] = MaybeUninit::slice_assume_init_ref(&buf[..k]);
|
||||
let slice: &[u16] = buf[..k].assume_init_ref();
|
||||
return Ok(f2(slice));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result<usiz
|
|||
assert!(result != 0, "Unexpected error in MultiByteToWideChar");
|
||||
|
||||
// Safety: MultiByteToWideChar initializes `result` values.
|
||||
MaybeUninit::slice_assume_init_ref(&utf16[..result as usize])
|
||||
utf16[..result as usize].assume_init_ref()
|
||||
};
|
||||
|
||||
let mut written = write_u16s(handle, utf16)?;
|
||||
|
@ -283,7 +283,7 @@ impl io::Read for Stdin {
|
|||
let read = read_u16s_fixup_surrogates(handle, &mut utf16_buf, 1, &mut self.surrogate)?;
|
||||
// Read bytes, using the (now-empty) self.incomplete_utf8 as extra space.
|
||||
let read_bytes = utf16_to_utf8(
|
||||
unsafe { MaybeUninit::slice_assume_init_ref(&utf16_buf[..read]) },
|
||||
unsafe { utf16_buf[..read].assume_init_ref() },
|
||||
&mut self.incomplete_utf8.bytes,
|
||||
)?;
|
||||
|
||||
|
@ -303,7 +303,7 @@ impl io::Read for Stdin {
|
|||
read_u16s_fixup_surrogates(handle, &mut utf16_buf, amount, &mut self.surrogate)?;
|
||||
// Safety `read_u16s_fixup_surrogates` returns the number of items
|
||||
// initialized.
|
||||
let utf16s = unsafe { MaybeUninit::slice_assume_init_ref(&utf16_buf[..read]) };
|
||||
let utf16s = unsafe { utf16_buf[..read].assume_init_ref() };
|
||||
match utf16_to_utf8(utf16s, buf) {
|
||||
Ok(value) => return Ok(bytes_copied + value),
|
||||
Err(e) => return Err(e),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue