@@ -2175,14 +2175,16 @@ pub unsafe trait FromZeros: TryFromBytes {
2175
2175
#[ cfg( feature = "alloc" ) ]
2176
2176
#[ cfg_attr( doc_cfg, doc( cfg( feature = "alloc" ) ) ) ]
2177
2177
#[ inline]
2178
- fn new_box_slice_zeroed ( len : usize ) -> Box < [ Self ] >
2178
+ fn new_box_zeroed_with_elems ( count : usize ) -> Option < Box < Self > >
2179
2179
where
2180
- Self : Sized ,
2180
+ Self : KnownLayout < PointerMetadata = usize > ,
2181
2181
{
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 ( ) ;
2186
2188
// On stable Rust versions <= 1.64.0, `Layout::from_size_align` has a
2187
2189
// bug in which sufficiently-large allocations (those which, when
2188
2190
// rounded up to the alignment, overflow `isize`) are not rejected,
@@ -2194,29 +2196,28 @@ pub unsafe trait FromZeros: TryFromBytes {
2194
2196
assert ! ( size <= max_alloc) ;
2195
2197
// TODO(https://github.com/rust-lang/rust/issues/55724): Use
2196
2198
// `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 ( ) ?;
2199
2200
2200
2201
let ptr = if layout. size ( ) != 0 {
2201
2202
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
2202
2203
#[ 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) ,
2206
2208
}
2207
- ptr
2208
2209
} else {
2209
2210
// `Box<[T]>` does not allocate when `T` is zero-sized or when `len`
2210
2211
// is zero, but it does require a non-null dangling pointer for its
2211
2212
// allocation.
2212
- NonNull :: < Self > :: dangling ( ) . as_ptr ( )
2213
+ NonNull :: < u8 > :: dangling ( )
2213
2214
} ;
2214
2215
2216
+ let ptr = Self :: raw_from_ptr_len ( ptr, count) ;
2217
+
2215
2218
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
2216
2219
#[ 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 ( ) ) } )
2220
2221
}
2221
2222
2222
2223
/// Creates a `Vec<Self>` from zeroed bytes.
@@ -2243,11 +2244,11 @@ pub unsafe trait FromZeros: TryFromBytes {
2243
2244
#[ cfg( feature = "alloc" ) ]
2244
2245
#[ cfg_attr( doc_cfg, doc( cfg( feature = "alloc" ) ) ) ]
2245
2246
#[ inline( always) ]
2246
- fn new_vec_zeroed ( len : usize ) -> Vec < Self >
2247
+ fn new_vec_zeroed ( len : usize ) -> Option < Vec < Self > >
2247
2248
where
2248
2249
Self : Sized ,
2249
2250
{
2250
- Self :: new_box_slice_zeroed ( len) . into ( )
2251
+ < [ Self ] > :: new_box_zeroed_with_elems ( len) . map ( Into :: into )
2251
2252
}
2252
2253
}
2253
2254
0 commit comments