`Box` and `Vec` don't properly document their behavior with zero-sized allocations for custom allocators
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Location (URL)
- https://doc.rust-lang.org/std/boxed/struct.Box.html#method.from_raw_in
- https://doc.rust-lang.org/std/vec/struct.Vec.html#method.from_raw_parts_in
- https://doc.rust-lang.org/std/boxed/struct.Box.html#method.into_raw_with_allocator
For each of these, also see the NonNull variant.
Summary
Box, Vec, and VecDeque all have special handling for zero-sized allocations, in that they do not go through the allocator. While this is fine to ignore for Global, as that allocator always returns NonNull::dangling for zero-sized allocations, this does not generalize to arbitrary allocators, as they may actually allocate (potentially overprovisioning), even for size = 0.
This poses a documentation problem for Box::from_raw_in and Vec::from_raw_parts_in, because they state that the memory will be freed on drop. However, this is incorrect if:
- For
Box<T, A>, the size of the value, as reported bysize_of_val_raw, is 0 (note that this applies to?Sizedtypes too) - For
Vec<T, A>, the capacity is 0 orTa ZST
Note that this also means their safety requirements are incorrect (overly strict), as they require passing a pointer to a memory block allocated with alloc. However, this incorrect and even inappropriate: as explained above, the memory will be leaked in certain cases.
Box::into_raw_with_allocator correctly links to the memory layout section, which describes the edge case (although for some reason it only talks about Global; needs rewrite too). However, I think this is not worded strongly enough. This is evidenced by me accidentally introducing an unsound deallocate call in Box::map in https://github.com/rust-lang/rust/pull/161617, which went undetected initially, and was fixed in https://github.com/rust-lang/rust/pull/162285.
Note that Vec::into_raw_parts_with_allocator is unaffected, as it states the only legal way to get rid of the memory is using from_raw_parts_in.
cc #156882
@rustbot label A-allocators requires-nightly
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked documentation for Box::from_raw_in, Vec::from_raw_parts_in, Box::into_raw_with_allocator, and their NonNull variants, then read the linked memory-layout section. Check how the text describes zero-sized values, zero capacity, ZSTs, and custom allocators. Done means the affected APIs and memory-layout documentation accurately describe allocation and deallocation behavior and their safety requirements.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100