From de91157389c4cf63ee6805e8490d0872fe2a7b33 Mon Sep 17 00:00:00 2001 From: The8472 Date: Thu, 5 Aug 2021 00:23:19 +0200 Subject: [PATCH] add Box::try_new_zeroed_slice() Currently there is no API that allows fallible zero-allocation of a Vec. Vec.try_reserve is not appropriate for this job since it doesn't know whether it should zero or arbitrary uninitialized memory is fine. Since Box currently holds most of the zeroing/uninit/slice allocation APIs it's the best place to add yet another entry into this feature matrix. --- library/alloc/src/boxed.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 53bfe02d0e7..e09cc227105 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -589,6 +589,38 @@ impl Box<[T]> { pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } } + + /// Constructs a new boxed slice with uninitialized contents, with the memory + /// being filled with `0` bytes. Returns an error if the allocation fails + /// + /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage + /// of this method. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api, new_uninit)] + /// + /// let values = Box::<[u32]>::try_new_zeroed_slice(3)?; + /// let values = unsafe { values.assume_init() }; + /// + /// assert_eq!(*values, [0, 0, 0]); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + /// + /// [zeroed]: mem::MaybeUninit::zeroed + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn try_new_zeroed_slice(len: usize) -> Result]>, AllocError> { + unsafe { + let layout = match Layout::array::>(len) { + Ok(l) => l, + Err(_) => return Err(AllocError), + }; + let ptr = Global.allocate_zeroed(layout)?; + Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) + } + } } impl Box<[T], A> {