Replace MaybeUninit::uninit_array() with array repeat expression.

This is possible now that inline const blocks are stable; the idea was
even mentioned as an alternative when `uninit_array()` was added:
<https://github.com/rust-lang/rust/pull/65580#issuecomment-544200681>

> if it’s stabilized soon enough maybe it’s not worth having a
> standard library method that will be replaceable with
> `let buffer = [MaybeUninit::<T>::uninit(); $N];`

Const array repetition and inline const blocks are now stable (in the
next release), so that circumstance has come to pass, and we no longer
have reason to want `uninit_array()` other than convenience. Therefore,
let’s evaluate the inconvenience by not using `uninit_array()` in
the standard library, before potentially deleting it entirely.
This commit is contained in:
Kevin Reid 2024-05-12 21:37:53 -07:00
parent d371d17496
commit 13fca73f49
22 changed files with 32 additions and 38 deletions

View File

@ -27,7 +27,6 @@
#![feature(lint_reasons)] #![feature(lint_reasons)]
#![feature(macro_metavar_expr)] #![feature(macro_metavar_expr)]
#![feature(map_try_insert)] #![feature(map_try_insert)]
#![feature(maybe_uninit_uninit_array)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(negative_impls)] #![feature(negative_impls)]
#![feature(never_type)] #![feature(never_type)]

View File

@ -188,7 +188,7 @@ impl SipHasher128 {
pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 { pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher128 {
let mut hasher = SipHasher128 { let mut hasher = SipHasher128 {
nbuf: 0, nbuf: 0,
buf: MaybeUninit::uninit_array(), buf: [MaybeUninit::uninit(); BUFFER_WITH_SPILL_CAPACITY],
state: State { state: State {
v0: key0 ^ 0x736f6d6570736575, v0: key0 ^ 0x736f6d6570736575,
// The XOR with 0xee is only done on 128-bit algorithm version. // The XOR with 0xee is only done on 128-bit algorithm version.

View File

@ -132,7 +132,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
fn next_chunk<const N: usize>( fn next_chunk<const N: usize>(
&mut self, &mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> { ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
let mut raw_arr = MaybeUninit::uninit_array(); let mut raw_arr = [const { MaybeUninit::uninit() }; N];
let raw_arr_ptr = raw_arr.as_mut_ptr().cast(); let raw_arr_ptr = raw_arr.as_mut_ptr().cast();
let (head, tail) = self.inner.as_slices(); let (head, tail) = self.inner.as_slices();

View File

@ -135,7 +135,6 @@
#![feature(layout_for_ptr)] #![feature(layout_for_ptr)]
#![feature(local_waker)] #![feature(local_waker)]
#![feature(maybe_uninit_slice)] #![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_uninit_array_transpose)] #![feature(maybe_uninit_uninit_array_transpose)]
#![feature(panic_internals)] #![feature(panic_internals)]
#![feature(pattern)] #![feature(pattern)]

View File

@ -254,7 +254,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
#[inline] #[inline]
fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> { fn next_chunk<const N: usize>(&mut self) -> Result<[T; N], core::array::IntoIter<T, N>> {
let mut raw_ary = MaybeUninit::uninit_array(); let mut raw_ary = [const { MaybeUninit::uninit() }; N];
let len = self.len(); let len = self.len();

View File

@ -101,7 +101,6 @@ impl<T, const N: usize> IntoIter<T, N> {
/// ``` /// ```
/// #![feature(array_into_iter_constructors)] /// #![feature(array_into_iter_constructors)]
/// #![feature(maybe_uninit_uninit_array_transpose)] /// #![feature(maybe_uninit_uninit_array_transpose)]
/// #![feature(maybe_uninit_uninit_array)]
/// use std::array::IntoIter; /// use std::array::IntoIter;
/// use std::mem::MaybeUninit; /// use std::mem::MaybeUninit;
/// ///
@ -111,7 +110,7 @@ impl<T, const N: usize> IntoIter<T, N> {
/// fn next_chunk<T: Copy, const N: usize>( /// fn next_chunk<T: Copy, const N: usize>(
/// it: &mut impl Iterator<Item = T>, /// it: &mut impl Iterator<Item = T>,
/// ) -> Result<[T; N], IntoIter<T, N>> { /// ) -> Result<[T; N], IntoIter<T, N>> {
/// let mut buffer = MaybeUninit::uninit_array(); /// let mut buffer = [const { MaybeUninit::uninit() }; N];
/// let mut i = 0; /// let mut i = 0;
/// while i < N { /// while i < N {
/// match it.next() { /// match it.next() {
@ -203,7 +202,7 @@ impl<T, const N: usize> IntoIter<T, N> {
#[unstable(feature = "array_into_iter_constructors", issue = "91583")] #[unstable(feature = "array_into_iter_constructors", issue = "91583")]
#[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")] #[rustc_const_unstable(feature = "const_array_into_iter_constructors", issue = "91583")]
pub const fn empty() -> Self { pub const fn empty() -> Self {
let buffer = MaybeUninit::uninit_array(); let buffer = [const { MaybeUninit::uninit() }; N];
let initialized = 0..0; let initialized = 0..0;
// SAFETY: We're telling it that none of the elements are initialized, // SAFETY: We're telling it that none of the elements are initialized,
@ -405,7 +404,8 @@ impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
// Note, we don't really need to match the exact same alive range, so // Note, we don't really need to match the exact same alive range, so
// we can just clone into offset 0 regardless of where `self` is. // we can just clone into offset 0 regardless of where `self` is.
let mut new = Self { data: MaybeUninit::uninit_array(), alive: IndexRange::zero_to(0) }; let mut new =
Self { data: [const { MaybeUninit::uninit() }; N], alive: IndexRange::zero_to(0) };
// Clone all alive elements. // Clone all alive elements.
for (src, dst) in iter::zip(self.as_slice(), &mut new.data) { for (src, dst) in iter::zip(self.as_slice(), &mut new.data) {

View File

@ -127,7 +127,7 @@ where
R: Try, R: Try,
R::Residual: Residual<[R::Output; N]>, R::Residual: Residual<[R::Output; N]>,
{ {
let mut array = MaybeUninit::uninit_array::<N>(); let mut array = [const { MaybeUninit::uninit() }; N];
match try_from_fn_erased(&mut array, cb) { match try_from_fn_erased(&mut array, cb) {
ControlFlow::Break(r) => FromResidual::from_residual(r), ControlFlow::Break(r) => FromResidual::from_residual(r),
ControlFlow::Continue(()) => { ControlFlow::Continue(()) => {
@ -918,7 +918,7 @@ impl<T> Drop for Guard<'_, T> {
pub(crate) fn iter_next_chunk<T, const N: usize>( pub(crate) fn iter_next_chunk<T, const N: usize>(
iter: &mut impl Iterator<Item = T>, iter: &mut impl Iterator<Item = T>,
) -> Result<[T; N], IntoIter<T, N>> { ) -> Result<[T; N], IntoIter<T, N>> {
let mut array = MaybeUninit::uninit_array::<N>(); let mut array = [const { MaybeUninit::uninit() }; N];
let r = iter_next_chunk_erased(&mut array, iter); let r = iter_next_chunk_erased(&mut array, iter);
match r { match r {
Ok(()) => { Ok(()) => {

View File

@ -35,8 +35,8 @@ fn float_to_decimal_common_exact<T>(
where where
T: flt2dec::DecodableFloat, T: flt2dec::DecodableFloat,
{ {
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 let mut buf: [MaybeUninit<u8>; 1024] = [MaybeUninit::uninit(); 1024]; // enough for f32 and f64
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array(); let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = [MaybeUninit::uninit(); 4];
let formatted = flt2dec::to_exact_fixed_str( let formatted = flt2dec::to_exact_fixed_str(
flt2dec::strategy::grisu::format_exact, flt2dec::strategy::grisu::format_exact,
*num, *num,
@ -62,8 +62,9 @@ where
T: flt2dec::DecodableFloat, T: flt2dec::DecodableFloat,
{ {
// enough for f32 and f64 // enough for f32 and f64
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] =
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = MaybeUninit::uninit_array(); [MaybeUninit::uninit(); flt2dec::MAX_SIG_DIGITS];
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 4] = [MaybeUninit::uninit(); 4];
let formatted = flt2dec::to_shortest_str( let formatted = flt2dec::to_shortest_str(
flt2dec::strategy::grisu::format_shortest, flt2dec::strategy::grisu::format_shortest,
*num, *num,
@ -107,8 +108,8 @@ fn float_to_exponential_common_exact<T>(
where where
T: flt2dec::DecodableFloat, T: flt2dec::DecodableFloat,
{ {
let mut buf: [MaybeUninit<u8>; 1024] = MaybeUninit::uninit_array(); // enough for f32 and f64 let mut buf: [MaybeUninit<u8>; 1024] = [MaybeUninit::uninit(); 1024]; // enough for f32 and f64
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array(); let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = [MaybeUninit::uninit(); 6];
let formatted = flt2dec::to_exact_exp_str( let formatted = flt2dec::to_exact_exp_str(
flt2dec::strategy::grisu::format_exact, flt2dec::strategy::grisu::format_exact,
*num, *num,
@ -135,8 +136,9 @@ where
T: flt2dec::DecodableFloat, T: flt2dec::DecodableFloat,
{ {
// enough for f32 and f64 // enough for f32 and f64
let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] = MaybeUninit::uninit_array(); let mut buf: [MaybeUninit<u8>; flt2dec::MAX_SIG_DIGITS] =
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = MaybeUninit::uninit_array(); [MaybeUninit::uninit(); flt2dec::MAX_SIG_DIGITS];
let mut parts: [MaybeUninit<numfmt::Part<'_>>; 6] = [MaybeUninit::uninit(); 6];
let formatted = flt2dec::to_shortest_exp_str( let formatted = flt2dec::to_shortest_exp_str(
flt2dec::strategy::grisu::format_shortest, flt2dec::strategy::grisu::format_shortest,
*num, *num,

View File

@ -202,7 +202,7 @@ where
T: Copy, T: Copy,
{ {
fn spec_next_chunk(&mut self) -> Result<[T; N], array::IntoIter<T, N>> { fn spec_next_chunk(&mut self) -> Result<[T; N], array::IntoIter<T, N>> {
let mut raw_array = MaybeUninit::uninit_array(); let mut raw_array = [const { MaybeUninit::uninit() }; N];
let len = self.len(); let len = self.len();

View File

@ -64,7 +64,7 @@ where
fn next_chunk<const N: usize>( fn next_chunk<const N: usize>(
&mut self, &mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> { ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
let mut array: [MaybeUninit<Self::Item>; N] = MaybeUninit::uninit_array(); let mut array: [MaybeUninit<Self::Item>; N] = [const { MaybeUninit::uninit() }; N];
struct Guard<'a, T> { struct Guard<'a, T> {
array: &'a mut [MaybeUninit<T>], array: &'a mut [MaybeUninit<T>],

View File

@ -68,7 +68,7 @@ where
fn next_chunk<const N: usize>( fn next_chunk<const N: usize>(
&mut self, &mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> { ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
let mut array: [MaybeUninit<Self::Item>; N] = MaybeUninit::uninit_array(); let mut array: [MaybeUninit<Self::Item>; N] = [const { MaybeUninit::uninit() }; N];
struct Guard<'a, T> { struct Guard<'a, T> {
array: &'a mut [MaybeUninit<T>], array: &'a mut [MaybeUninit<T>],

View File

@ -110,7 +110,8 @@ impl<I: Iterator, const N: usize> MapWindowsInner<I, N> {
impl<T, const N: usize> Buffer<T, N> { impl<T, const N: usize> Buffer<T, N> {
fn try_from_iter(iter: &mut impl Iterator<Item = T>) -> Option<Self> { fn try_from_iter(iter: &mut impl Iterator<Item = T>) -> Option<Self> {
let first_half = crate::array::iter_next_chunk(iter).ok()?; let first_half = crate::array::iter_next_chunk(iter).ok()?;
let buffer = [MaybeUninit::new(first_half).transpose(), MaybeUninit::uninit_array()]; let buffer =
[MaybeUninit::new(first_half).transpose(), [const { MaybeUninit::uninit() }; N]];
Some(Self { buffer, start: 0 }) Some(Self { buffer, start: 0 })
} }
@ -204,7 +205,7 @@ impl<T, const N: usize> Buffer<T, N> {
impl<T: Clone, const N: usize> Clone for Buffer<T, N> { impl<T: Clone, const N: usize> Clone for Buffer<T, N> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
let mut buffer = Buffer { let mut buffer = Buffer {
buffer: [MaybeUninit::uninit_array(), MaybeUninit::uninit_array()], buffer: [[const { MaybeUninit::uninit() }; N], [const { MaybeUninit::uninit() }; N]],
start: self.start, start: self.start,
}; };
buffer.as_uninit_array_mut().write(self.as_array_ref().clone()); buffer.as_uninit_array_mut().write(self.as_array_ref().clone());

View File

@ -140,7 +140,6 @@
#![feature(const_likely)] #![feature(const_likely)]
#![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_maybe_uninit_assume_init)] #![feature(const_maybe_uninit_assume_init)]
#![feature(const_maybe_uninit_uninit_array)]
#![feature(const_nonnull_new)] #![feature(const_nonnull_new)]
#![feature(const_num_midpoint)] #![feature(const_num_midpoint)]
#![feature(const_option)] #![feature(const_option)]
@ -177,7 +176,6 @@
#![feature(is_ascii_octdigit)] #![feature(is_ascii_octdigit)]
#![feature(isqrt)] #![feature(isqrt)]
#![feature(link_cfg)] #![feature(link_cfg)]
#![feature(maybe_uninit_uninit_array)]
#![feature(offset_of_enum)] #![feature(offset_of_enum)]
#![feature(offset_of_nested)] #![feature(offset_of_nested)]
#![feature(panic_internals)] #![feature(panic_internals)]

View File

@ -917,11 +917,10 @@ impl<T> MaybeUninit<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(maybe_uninit_uninit_array)]
/// #![feature(maybe_uninit_array_assume_init)] /// #![feature(maybe_uninit_array_assume_init)]
/// use std::mem::MaybeUninit; /// use std::mem::MaybeUninit;
/// ///
/// let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array(); /// let mut array: [MaybeUninit<i32>; 3] = [MaybeUninit::uninit(); 3];
/// array[0].write(0); /// array[0].write(0);
/// array[1].write(1); /// array[1].write(1);
/// array[2].write(2); /// array[2].write(2);

View File

@ -11,7 +11,7 @@ pub struct DisplayBuffer<const SIZE: usize> {
impl<const SIZE: usize> DisplayBuffer<SIZE> { impl<const SIZE: usize> DisplayBuffer<SIZE> {
#[inline] #[inline]
pub const fn new() -> Self { pub const fn new() -> Self {
Self { buf: MaybeUninit::uninit_array(), len: 0 } Self { buf: [MaybeUninit::uninit(); SIZE], len: 0 }
} }
#[inline] #[inline]

View File

@ -104,7 +104,7 @@ struct AlignedStorage<T, const N: usize> {
impl<T, const N: usize> AlignedStorage<T, N> { impl<T, const N: usize> AlignedStorage<T, N> {
fn new() -> Self { fn new() -> Self {
Self { _align: [], storage: MaybeUninit::uninit_array() } Self { _align: [], storage: [const { MaybeUninit::uninit() }; N] }
} }
fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] { fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {

View File

@ -54,8 +54,6 @@
#![feature(slice_split_once)] #![feature(slice_split_once)]
#![feature(split_as_slice)] #![feature(split_as_slice)]
#![feature(maybe_uninit_fill)] #![feature(maybe_uninit_fill)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)] #![feature(maybe_uninit_write_slice)]
#![feature(maybe_uninit_uninit_array_transpose)] #![feature(maybe_uninit_uninit_array_transpose)]
#![feature(min_specialization)] #![feature(min_specialization)]

View File

@ -406,7 +406,7 @@ fn file_test_read_buf() {
let filename = &tmpdir.join("test"); let filename = &tmpdir.join("test");
check!(fs::write(filename, &[1, 2, 3, 4])); check!(fs::write(filename, &[1, 2, 3, 4]));
let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array(); let mut buf: [MaybeUninit<u8>; 128] = [MaybeUninit::uninit(); 128];
let mut buf = BorrowedBuf::from(buf.as_mut_slice()); let mut buf = BorrowedBuf::from(buf.as_mut_slice());
let mut file = check!(File::open(filename)); let mut file = check!(File::open(filename));
check!(file.read_buf(buf.unfilled())); check!(file.read_buf(buf.unfilled()));

View File

@ -337,7 +337,6 @@
#![feature(hint_assert_unchecked)] #![feature(hint_assert_unchecked)]
#![feature(ip)] #![feature(ip)]
#![feature(maybe_uninit_slice)] #![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)] #![feature(maybe_uninit_write_slice)]
#![feature(panic_can_unwind)] #![feature(panic_can_unwind)]
#![feature(panic_info_message)] #![feature(panic_info_message)]
@ -407,7 +406,6 @@
#![feature(const_ip)] #![feature(const_ip)]
#![feature(const_ipv4)] #![feature(const_ipv4)]
#![feature(const_ipv6)] #![feature(const_ipv6)]
#![feature(const_maybe_uninit_uninit_array)]
#![feature(const_waker)] #![feature(const_waker)]
#![feature(thread_local_internals)] #![feature(thread_local_internals)]
// tidy-alphabetical-end // tidy-alphabetical-end

View File

@ -301,7 +301,7 @@ fn read_buf() {
}); });
let mut s = t!(srv.accept()).0; let mut s = t!(srv.accept()).0;
let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array(); let mut buf: [MaybeUninit<u8>; 128] = [MaybeUninit::uninit(); 128];
let mut buf = BorrowedBuf::from(buf.as_mut_slice()); let mut buf = BorrowedBuf::from(buf.as_mut_slice());
t!(s.read_buf(buf.unfilled())); t!(s.read_buf(buf.unfilled()));
assert_eq!(buf.filled(), &[1, 2, 3, 4]); assert_eq!(buf.filled(), &[1, 2, 3, 4]);

View File

@ -137,7 +137,7 @@ fn child_stdout_read_buf() {
let child = cmd.spawn().unwrap(); let child = cmd.spawn().unwrap();
let mut stdout = child.stdout.unwrap(); let mut stdout = child.stdout.unwrap();
let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array(); let mut buf: [MaybeUninit<u8>; 128] = [MaybeUninit::uninit(); 128];
let mut buf = BorrowedBuf::from(buf.as_mut_slice()); let mut buf = BorrowedBuf::from(buf.as_mut_slice());
stdout.read_buf(buf.unfilled()).unwrap(); stdout.read_buf(buf.unfilled()).unwrap();

View File

@ -227,7 +227,7 @@ where
// This initial size also works around `GetFullPathNameW` returning // This initial size also works around `GetFullPathNameW` returning
// incorrect size hints for some short paths: // incorrect size hints for some short paths:
// https://github.com/dylni/normpath/issues/5 // https://github.com/dylni/normpath/issues/5
let mut stack_buf: [MaybeUninit<u16>; 512] = MaybeUninit::uninit_array(); let mut stack_buf: [MaybeUninit<u16>; 512] = [MaybeUninit::uninit(); 512];
let mut heap_buf: Vec<MaybeUninit<u16>> = Vec::new(); let mut heap_buf: Vec<MaybeUninit<u16>> = Vec::new();
unsafe { unsafe {
let mut n = stack_buf.len(); let mut n = stack_buf.len();