From 2c14dd3b12d29749465a84429a4643da5c4e3934 Mon Sep 17 00:00:00 2001 From: Aljoscha Meyer Date: Sat, 6 Jul 2024 09:09:10 +0200 Subject: [PATCH 1/5] Add missing try_new_uninit_slice_in and try_new_zeroed_slice_in The methods for fallible slice allocation in a given allocator were missing, which was an oversight according to https://github.com/rust-lang/wg-allocators/issues/130 This PR adds them as `try_new_uninit_slice_in` and `try_new_zeroed_slice_in`. Also adds missing punctuation to the doc comments of ` try_new_uninit_slice` and `try_new_zeroed_slice` --- library/alloc/src/boxed.rs | 77 +++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 1ec095a46f704..d67b0ac37eb1f 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -704,7 +704,7 @@ impl Box<[T]> { } /// Constructs a new boxed slice with uninitialized contents. Returns an error if - /// the allocation fails + /// the allocation fails. /// /// # Examples /// @@ -739,7 +739,7 @@ impl Box<[T]> { } /// Constructs a new boxed slice with uninitialized contents, with the memory - /// being filled with `0` bytes. Returns an error if the allocation fails + /// 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. @@ -831,6 +831,79 @@ impl Box<[T], A> { pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } } + + /// Constructs a new boxed slice with uninitialized contents in the provided allocator. Returns an error if + /// the allocation fails. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api, new_uninit)] + /// + /// use std::alloc::System; + /// + /// let mut values = Box::<[u32]>::try_new_uninit_slice(3, System)?; + /// let values = unsafe { + /// // Deferred initialization: + /// values[0].as_mut_ptr().write(1); + /// values[1].as_mut_ptr().write(2); + /// values[2].as_mut_ptr().write(3); + /// values.assume_init() + /// }; + /// + /// assert_eq!(*values, [1, 2, 3]); + /// # Ok::<(), std::alloc::AllocError>(()) + /// ``` + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn try_new_uninit_slice_in(len: usize, alloc: A) -> Result], A>, AllocError> { + let ptr = if T::IS_ZST || len == 0 { + NonNull::dangling() + } else { + let layout = match Layout::array::>(len) { + Ok(l) => l, + Err(_) => return Err(AllocError), + }; + Global.allocate(layout)?.cast() + }; + unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } + } + + /// Constructs a new boxed slice with uninitialized contents in the provided allocator, 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)] + /// + /// use std::alloc::System; + /// + /// let values = Box::<[u32]>::try_new_zeroed_slice(3, System)?; + /// 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_in(len: usize, alloc: A) -> Result], A>, AllocError> { + let ptr = if T::IS_ZST || len == 0 { + NonNull::dangling() + } else { + let layout = match Layout::array::>(len) { + Ok(l) => l, + Err(_) => return Err(AllocError), + }; + Global.allocate_zeroed(layout)?.cast() + }; + unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } + } } impl Box, A> { From 9bfdeb592c422b355ac96086dbac8a6dfdaa6c73 Mon Sep 17 00:00:00 2001 From: Aljoscha Meyer Date: Sat, 6 Jul 2024 14:38:00 +0200 Subject: [PATCH 2/5] Run formatter on alloc/src/boxed.rs --- library/alloc/src/boxed.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index d67b0ac37eb1f..b817cf855a5e7 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -839,7 +839,7 @@ impl Box<[T], A> { /// /// ``` /// #![feature(allocator_api, new_uninit)] - /// + /// /// use std::alloc::System; /// /// let mut values = Box::<[u32]>::try_new_uninit_slice(3, System)?; @@ -856,7 +856,10 @@ impl Box<[T], A> { /// ``` #[unstable(feature = "allocator_api", issue = "32838")] #[inline] - pub fn try_new_uninit_slice_in(len: usize, alloc: A) -> Result], A>, AllocError> { + pub fn try_new_uninit_slice_in( + len: usize, + alloc: A, + ) -> Result], A>, AllocError> { let ptr = if T::IS_ZST || len == 0 { NonNull::dangling() } else { @@ -879,7 +882,7 @@ impl Box<[T], A> { /// /// ``` /// #![feature(allocator_api, new_uninit)] - /// + /// /// use std::alloc::System; /// /// let values = Box::<[u32]>::try_new_zeroed_slice(3, System)?; @@ -892,7 +895,10 @@ impl Box<[T], A> { /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] #[inline] - pub fn try_new_zeroed_slice_in(len: usize, alloc: A) -> Result], A>, AllocError> { + pub fn try_new_zeroed_slice_in( + len: usize, + alloc: A, + ) -> Result], A>, AllocError> { let ptr = if T::IS_ZST || len == 0 { NonNull::dangling() } else { From 6b5da82d12a81e4905a9e01a33d4831fe6fea9ec Mon Sep 17 00:00:00 2001 From: Aljoscha Meyer Date: Sat, 6 Jul 2024 18:50:03 +0200 Subject: [PATCH 3/5] Fix doc examples --- library/alloc/src/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index b817cf855a5e7..847594103d50d 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -842,7 +842,7 @@ impl Box<[T], A> { /// /// use std::alloc::System; /// - /// let mut values = Box::<[u32]>::try_new_uninit_slice(3, System)?; + /// let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, System)?; /// let values = unsafe { /// // Deferred initialization: /// values[0].as_mut_ptr().write(1); @@ -885,7 +885,7 @@ impl Box<[T], A> { /// /// use std::alloc::System; /// - /// let values = Box::<[u32]>::try_new_zeroed_slice(3, System)?; + /// let values = Box::<[u32]>::try_new_zeroed_slice_in(3, System)?; /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [0, 0, 0]); From 497ef498053be7e6ef9e8af1bf7dc1e8800674c1 Mon Sep 17 00:00:00 2001 From: Aljoscha Meyer Date: Sat, 6 Jul 2024 19:13:53 +0200 Subject: [PATCH 4/5] Fix them doc examples some more Apologies for the many attempts, my dev loop for this consists of editing on github, committing, and then waiting for the CI failure log to yell at me. --- library/alloc/src/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 847594103d50d..322c0756abdb3 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -842,7 +842,7 @@ impl Box<[T], A> { /// /// use std::alloc::System; /// - /// let mut values = Box::<[u32]>::try_new_uninit_slice_in(3, System)?; + /// let mut values = Box::<[u32], _>::try_new_uninit_slice_in(3, System)?; /// let values = unsafe { /// // Deferred initialization: /// values[0].as_mut_ptr().write(1); @@ -885,7 +885,7 @@ impl Box<[T], A> { /// /// use std::alloc::System; /// - /// let values = Box::<[u32]>::try_new_zeroed_slice_in(3, System)?; + /// let values = Box::<[u32], _>::try_new_zeroed_slice_in(3, System)?; /// let values = unsafe { values.assume_init() }; /// /// assert_eq!(*values, [0, 0, 0]); From 351fe273547ac57ddf829b358dff538ab587599a Mon Sep 17 00:00:00 2001 From: Aljoscha Meyer Date: Mon, 22 Jul 2024 08:17:46 +0200 Subject: [PATCH 5/5] Use given allocator instad of Global --- library/alloc/src/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 322c0756abdb3..5117f883af2b6 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -867,7 +867,7 @@ impl Box<[T], A> { Ok(l) => l, Err(_) => return Err(AllocError), }; - Global.allocate(layout)?.cast() + alloc.allocate(layout)?.cast() }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } @@ -906,7 +906,7 @@ impl Box<[T], A> { Ok(l) => l, Err(_) => return Err(AllocError), }; - Global.allocate_zeroed(layout)?.cast() + alloc.allocate_zeroed(layout)?.cast() }; unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } }