mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Rollup merge of #139072 - nickkuk:align_to_uninit_mut, r=Mark-Simulacrum
Add `slice::align_to_uninit_mut` Add new `slice::align_to_uninit_mut` method. Tracking issue: https://github.com/rust-lang/rust/issues/139062 ACP: https://github.com/rust-lang/libs-team/issues/564
This commit is contained in:
commit
d1da78b201
@ -8,7 +8,7 @@
|
||||
|
||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use crate::intrinsics::{exact_div, unchecked_sub};
|
||||
use crate::mem::{self, SizedTypeProperties};
|
||||
use crate::mem::{self, MaybeUninit, SizedTypeProperties};
|
||||
use crate::num::NonZero;
|
||||
use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive};
|
||||
use crate::panic::const_panic;
|
||||
@ -4579,7 +4579,7 @@ impl<T> [T] {
|
||||
// or generate worse code otherwise. This is also why we need to go
|
||||
// through a raw pointer here.
|
||||
let slice: *mut [T] = self;
|
||||
let mut arr: mem::MaybeUninit<[&mut I::Output; N]> = mem::MaybeUninit::uninit();
|
||||
let mut arr: MaybeUninit<[&mut I::Output; N]> = MaybeUninit::uninit();
|
||||
let arr_ptr = arr.as_mut_ptr();
|
||||
|
||||
// SAFETY: We expect `indices` to contain disjunct values that are
|
||||
@ -4764,6 +4764,55 @@ impl<T> [T] {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> [MaybeUninit<T>] {
|
||||
/// Transmutes the mutable uninitialized slice to a mutable uninitialized slice of
|
||||
/// another type, ensuring alignment of the types is maintained.
|
||||
///
|
||||
/// This is a safe wrapper around [`slice::align_to_mut`], so inherits the same
|
||||
/// guarantees as that method.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(align_to_uninit_mut)]
|
||||
/// use std::mem::MaybeUninit;
|
||||
///
|
||||
/// pub struct BumpAllocator<'scope> {
|
||||
/// memory: &'scope mut [MaybeUninit<u8>],
|
||||
/// }
|
||||
///
|
||||
/// impl<'scope> BumpAllocator<'scope> {
|
||||
/// pub fn new(memory: &'scope mut [MaybeUninit<u8>]) -> Self {
|
||||
/// Self { memory }
|
||||
/// }
|
||||
/// pub fn try_alloc_uninit<T>(&mut self) -> Option<&'scope mut MaybeUninit<T>> {
|
||||
/// let first_end = self.memory.as_ptr().align_offset(align_of::<T>()) + size_of::<T>();
|
||||
/// let prefix = self.memory.split_off_mut(..first_end)?;
|
||||
/// Some(&mut prefix.align_to_uninit_mut::<T>().1[0])
|
||||
/// }
|
||||
/// pub fn try_alloc_u32(&mut self, value: u32) -> Option<&'scope mut u32> {
|
||||
/// let uninit = self.try_alloc_uninit()?;
|
||||
/// Some(uninit.write(value))
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let mut memory = [MaybeUninit::<u8>::uninit(); 10];
|
||||
/// let mut allocator = BumpAllocator::new(&mut memory);
|
||||
/// let v = allocator.try_alloc_u32(42);
|
||||
/// assert_eq!(v, Some(&mut 42));
|
||||
/// ```
|
||||
#[unstable(feature = "align_to_uninit_mut", issue = "139062")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn align_to_uninit_mut<U>(&mut self) -> (&mut Self, &mut [MaybeUninit<U>], &mut Self) {
|
||||
// SAFETY: `MaybeUninit` is transparent. Correct size and alignment are guaranteed by
|
||||
// `align_to_mut` itself. Therefore the only thing that we have to ensure for a safe
|
||||
// `transmute` is that the values are valid for the types involved. But for `MaybeUninit`
|
||||
// any values are valid, so this operation is safe.
|
||||
unsafe { self.align_to_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const N: usize> [[T; N]] {
|
||||
/// Takes a `&[[T; N]]`, and flattens it to a `&[T]`.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user