Description
Location
https://github.com/rust-lang/rust/blob/master/library/alloc/src/boxed.rs#L205
https://github.com/rust-lang/rust/blob/master/library/alloc/src/boxed.rs#L293
https://github.com/rust-lang/rust/blob/master/library/alloc/src/boxed.rs#L366
https://github.com/rust-lang/rust/blob/master/library/alloc/src/boxed.rs#L396
Summary
In the provided locations for documentation of various Box
constructors, the documentation indicates the documented functions will not allocate if the T
is zero-sized. However, looking through the call paths of these functions, no ZST-handling is present—ostensibly, the call-path is relying on an undocumented behaviour of expectation that when Box
does finally call .allocate
, the provided (global or otherwise) allocator will panic or return an error.
For what I hope are obvious reasons, this isn't the expected behaviour. For instance, this is how I implemented ZST handling:
const T_IS_ZST: bool = core::mem::size_of::<T>() == 0;
pub fn new_in(value: T, allocator: A) -> AllocResult<Self> {
if Self::T_IS_ZST {
// We don't need to allocate anything if the type is zero-sized.
Ok(Self {
ptr: NonNull::dangling(),
allocator,
})
} else {
allocator.allocate(Layout::new::<T>()).map(|allocation| {
let ptr = allocation.as_non_null_ptr().cast::<T>();
// ### Safety: Memory is guaranteed valid for T's layout by allocator API safety.
unsafe { ptr.as_ptr().write(value) };
Self { ptr, allocator }
})
}
}
It seems disingenuous to me for Box
to claim it will not allocate for ZSTs, but then have the only possible call path result in a call to Allocator::allocate
.