From c3b602af8ce5800971c323f5eead66504c0ecce7 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` --- alloc/src/boxed.rs | 77 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index 1ec095a46f704..d67b0ac37eb1f 100644 --- a/alloc/src/boxed.rs +++ b/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 8d0199656c4137b9e3d6c34f8996ab1c4f4bda47 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 --- alloc/src/boxed.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index d67b0ac37eb1f..b817cf855a5e7 100644 --- a/alloc/src/boxed.rs +++ b/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 be23cef3a427257417387da460fdd7100f11c0c2 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 --- alloc/src/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index b817cf855a5e7..847594103d50d 100644 --- a/alloc/src/boxed.rs +++ b/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 ca537d2cb337ab77c3f21d2802f956e363adfebf 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. --- alloc/src/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index 847594103d50d..322c0756abdb3 100644 --- a/alloc/src/boxed.rs +++ b/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 d6a36f520f5903ec5abbedf81f769593a7020b74 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 --- alloc/src/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alloc/src/boxed.rs b/alloc/src/boxed.rs index 322c0756abdb3..5117f883af2b6 100644 --- a/alloc/src/boxed.rs +++ b/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)) } }