|
8 | 8 |
|
9 | 9 | use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
10 | 10 | use crate::intrinsics::{exact_div, unchecked_sub};
|
11 |
| -use crate::mem::{self, SizedTypeProperties}; |
| 11 | +use crate::mem::{self, MaybeUninit, SizedTypeProperties}; |
12 | 12 | use crate::num::NonZero;
|
13 | 13 | use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive};
|
14 | 14 | use crate::panic::const_panic;
|
@@ -4579,7 +4579,7 @@ impl<T> [T] {
|
4579 | 4579 | // or generate worse code otherwise. This is also why we need to go
|
4580 | 4580 | // through a raw pointer here.
|
4581 | 4581 | let slice: *mut [T] = self;
|
4582 |
| - let mut arr: mem::MaybeUninit<[&mut I::Output; N]> = mem::MaybeUninit::uninit(); |
| 4582 | + let mut arr: MaybeUninit<[&mut I::Output; N]> = MaybeUninit::uninit(); |
4583 | 4583 | let arr_ptr = arr.as_mut_ptr();
|
4584 | 4584 |
|
4585 | 4585 | // SAFETY: We expect `indices` to contain disjunct values that are
|
@@ -4764,6 +4764,55 @@ impl<T> [T] {
|
4764 | 4764 | }
|
4765 | 4765 | }
|
4766 | 4766 |
|
| 4767 | +impl<T> [MaybeUninit<T>] { |
| 4768 | + /// Transmutes the mutable uninitialized slice to a mutable uninitialized slice of |
| 4769 | + /// another type, ensuring alignment of the types is maintained. |
| 4770 | + /// |
| 4771 | + /// This is a safe wrapper around [`slice::align_to_mut`], so inherits the same |
| 4772 | + /// guarantees as that method. |
| 4773 | + /// |
| 4774 | + /// # Examples |
| 4775 | + /// |
| 4776 | + /// ``` |
| 4777 | + /// #![feature(align_to_uninit_mut)] |
| 4778 | + /// use std::mem::MaybeUninit; |
| 4779 | + /// |
| 4780 | + /// pub struct BumpAllocator<'scope> { |
| 4781 | + /// memory: &'scope mut [MaybeUninit<u8>], |
| 4782 | + /// } |
| 4783 | + /// |
| 4784 | + /// impl<'scope> BumpAllocator<'scope> { |
| 4785 | + /// pub fn new(memory: &'scope mut [MaybeUninit<u8>]) -> Self { |
| 4786 | + /// Self { memory } |
| 4787 | + /// } |
| 4788 | + /// pub fn try_alloc_uninit<T>(&mut self) -> Option<&'scope mut MaybeUninit<T>> { |
| 4789 | + /// let first_end = self.memory.as_ptr().align_offset(align_of::<T>()) + size_of::<T>(); |
| 4790 | + /// let prefix = self.memory.split_off_mut(..first_end)?; |
| 4791 | + /// Some(&mut prefix.align_to_uninit_mut::<T>().1[0]) |
| 4792 | + /// } |
| 4793 | + /// pub fn try_alloc_u32(&mut self, value: u32) -> Option<&'scope mut u32> { |
| 4794 | + /// let uninit = self.try_alloc_uninit()?; |
| 4795 | + /// Some(uninit.write(value)) |
| 4796 | + /// } |
| 4797 | + /// } |
| 4798 | + /// |
| 4799 | + /// let mut memory = [MaybeUninit::<u8>::uninit(); 10]; |
| 4800 | + /// let mut allocator = BumpAllocator::new(&mut memory); |
| 4801 | + /// let v = allocator.try_alloc_u32(42); |
| 4802 | + /// assert_eq!(v, Some(&mut 42)); |
| 4803 | + /// ``` |
| 4804 | + #[unstable(feature = "align_to_uninit_mut", issue = "139062")] |
| 4805 | + #[inline] |
| 4806 | + #[must_use] |
| 4807 | + pub fn align_to_uninit_mut<U>(&mut self) -> (&mut Self, &mut [MaybeUninit<U>], &mut Self) { |
| 4808 | + // SAFETY: `MaybeUninit` is transparent. Correct size and alignment are guaranteed by |
| 4809 | + // `align_to_mut` itself. Therefore the only thing that we have to ensure for a safe |
| 4810 | + // `transmute` is that the values are valid for the types involved. But for `MaybeUninit` |
| 4811 | + // any values are valid, so this operation is safe. |
| 4812 | + unsafe { self.align_to_mut() } |
| 4813 | + } |
| 4814 | +} |
| 4815 | + |
4767 | 4816 | impl<T, const N: usize> [[T; N]] {
|
4768 | 4817 | /// Takes a `&[[T; N]]`, and flattens it to a `&[T]`.
|
4769 | 4818 | ///
|
|
0 commit comments