Rollup merge of #127415 - AljoschaMeyer:master, r=dtolnay
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 from `Box`, 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`. I simply copy-pasted the implementations of `try_new_uninit_slice` and `try_new_zeroed_slice` and adusted doc comment, typings, and the allocator it uses internally. Also adds missing punctuation to the doc comments of `try_new_uninit_slice` and `try_new_zeroed_slice`. Related issue is https://github.com/rust-lang/rust/issues/32838 (Allocator traits and std::heap) *I think*. Also relevant is https://github.com/rust-lang/rust/issues/63291, but I did not add the corresponding `#[unstable]` proc macro, since `try_new_uninit_slice` and `try_new_zeroed_slice` are also not annotated with it.
This commit is contained in:
commit
9f4039fcd5
1 changed files with 81 additions and 2 deletions
|
@ -704,7 +704,7 @@ impl<T> Box<[T]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new boxed slice with uninitialized contents. Returns an error if
|
/// Constructs a new boxed slice with uninitialized contents. Returns an error if
|
||||||
/// the allocation fails
|
/// the allocation fails.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -739,7 +739,7 @@ impl<T> Box<[T]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new boxed slice with uninitialized contents, with the memory
|
/// 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
|
/// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
|
||||||
/// of this method.
|
/// of this method.
|
||||||
|
@ -831,6 +831,85 @@ impl<T, A: Allocator> Box<[T], A> {
|
||||||
pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
|
pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
|
||||||
unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) }
|
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_in(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<Box<[mem::MaybeUninit<T>], A>, AllocError> {
|
||||||
|
let ptr = if T::IS_ZST || len == 0 {
|
||||||
|
NonNull::dangling()
|
||||||
|
} else {
|
||||||
|
let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
|
||||||
|
Ok(l) => l,
|
||||||
|
Err(_) => return Err(AllocError),
|
||||||
|
};
|
||||||
|
alloc.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_in(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<Box<[mem::MaybeUninit<T>], A>, AllocError> {
|
||||||
|
let ptr = if T::IS_ZST || len == 0 {
|
||||||
|
NonNull::dangling()
|
||||||
|
} else {
|
||||||
|
let layout = match Layout::array::<mem::MaybeUninit<T>>(len) {
|
||||||
|
Ok(l) => l,
|
||||||
|
Err(_) => return Err(AllocError),
|
||||||
|
};
|
||||||
|
alloc.allocate_zeroed(layout)?.cast()
|
||||||
|
};
|
||||||
|
unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
|
impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
|
||||||
|
|
Loading…
Add table
Reference in a new issue