Skip to content

Commit a61e5f0

Browse files
committed
FromZeros boxed slice method supports slice DSTs
Makes progress on #29
1 parent 52e3577 commit a61e5f0

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

src/lib.rs

+19-18
Original file line numberDiff line numberDiff line change
@@ -2175,14 +2175,16 @@ pub unsafe trait FromZeros: TryFromBytes {
21752175
#[cfg(feature = "alloc")]
21762176
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
21772177
#[inline]
2178-
fn new_box_slice_zeroed(len: usize) -> Box<[Self]>
2178+
fn new_box_zeroed_with_elems(count: usize) -> Option<Box<Self>>
21792179
where
2180-
Self: Sized,
2180+
Self: KnownLayout<PointerMetadata = usize>,
21812181
{
2182-
let size = mem::size_of::<Self>()
2183-
.checked_mul(len)
2184-
.expect("mem::size_of::<Self>() * len overflows `usize`");
2185-
let align = mem::align_of::<Self>();
2182+
let size = match count.size_for_metadata(Self::LAYOUT) {
2183+
Some(size) => size,
2184+
None => return None,
2185+
};
2186+
2187+
let align = Self::LAYOUT.align.get();
21862188
// On stable Rust versions <= 1.64.0, `Layout::from_size_align` has a
21872189
// bug in which sufficiently-large allocations (those which, when
21882190
// rounded up to the alignment, overflow `isize`) are not rejected,
@@ -2194,29 +2196,28 @@ pub unsafe trait FromZeros: TryFromBytes {
21942196
assert!(size <= max_alloc);
21952197
// TODO(https://github.com/rust-lang/rust/issues/55724): Use
21962198
// `Layout::repeat` once it's stabilized.
2197-
let layout =
2198-
Layout::from_size_align(size, align).expect("total allocation size overflows `isize`");
2199+
let layout = Layout::from_size_align(size, align).ok()?;
21992200

22002201
let ptr = if layout.size() != 0 {
22012202
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
22022203
#[allow(clippy::undocumented_unsafe_blocks)]
2203-
let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
2204-
if ptr.is_null() {
2205-
alloc::alloc::handle_alloc_error(layout);
2204+
let ptr = unsafe { alloc::alloc::alloc_zeroed(layout) };
2205+
match NonNull::new(ptr) {
2206+
Some(ptr) => ptr,
2207+
None => alloc::alloc::handle_alloc_error(layout),
22062208
}
2207-
ptr
22082209
} else {
22092210
// `Box<[T]>` does not allocate when `T` is zero-sized or when `len`
22102211
// is zero, but it does require a non-null dangling pointer for its
22112212
// allocation.
2212-
NonNull::<Self>::dangling().as_ptr()
2213+
NonNull::<u8>::dangling()
22132214
};
22142215

2216+
let ptr = Self::raw_from_ptr_len(ptr, count);
2217+
22152218
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
22162219
#[allow(clippy::undocumented_unsafe_blocks)]
2217-
unsafe {
2218-
Box::from_raw(slice::from_raw_parts_mut(ptr, len))
2219-
}
2220+
Some(unsafe { Box::from_raw(ptr.as_ptr()) })
22202221
}
22212222

22222223
/// Creates a `Vec<Self>` from zeroed bytes.
@@ -2243,11 +2244,11 @@ pub unsafe trait FromZeros: TryFromBytes {
22432244
#[cfg(feature = "alloc")]
22442245
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
22452246
#[inline(always)]
2246-
fn new_vec_zeroed(len: usize) -> Vec<Self>
2247+
fn new_vec_zeroed(len: usize) -> Option<Vec<Self>>
22472248
where
22482249
Self: Sized,
22492250
{
2250-
Self::new_box_slice_zeroed(len).into()
2251+
<[Self]>::new_box_zeroed_with_elems(len).map(Into::into)
22512252
}
22522253
}
22532254

0 commit comments

Comments
 (0)