Clarify safety invariants in Vec::from_raw_parts
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Location
https://doc.rust-lang.org/std/vec/struct.Vec.html#method.from_raw_parts
Summary
Currently the documentation of Vec::from_raw_parts claims that both:
- The size of
Ttimes thecapacity(ie. the allocated size in bytes) needs to be the same size as the pointer was allocated with. capacityneeds to be the capacity that the pointer was allocated with.
This is somewhat confusing. The first condition arises from #95016 which explicitly removed the second condition in favor of the first. The second condition was then added back in in #99216 without any specific comment about it being necessary.
Together these conditions imply that T needs to have the same size and alignment as what ptr was allocated with. But the whole point of #95016 is that this isn't actually the case. (If this is actually the case, I think this could be reworded to be more clear)
Broadly what I am trying to understand is if the following 2 bits of code which convert between Vec<[T; N]> and Vec<T> are UB or not:
fn flatten<const N: usize>(vec: Vec<[T; N]>) -> Vec<T> {
let mut v = mem::ManuallyDrop::new(v);
let len = v.len() * N;
let cap = v.capacity() * N;
let p = v.as_mut_ptr() as *mut T;
unsafe {
Vec::from_raw_parts(ptr, new_len, new_cap)
}
}
fn recombine<const N: usize>(vec: Vec<T>) -> Vec<[T; N]> {
let mut v = mem::ManuallyDrop::new(v);
assert_eq!(v.len() % N == 0);
assert_eq!(v.capacity() % N == 0);
let len = v.len() / N;
let cap = v.capacity() / N;
let p = v.as_mut_ptr() as *mut [T; N];
unsafe {
Vec::from_raw_parts(ptr, new_len, new_cap)
}
}
As far as I can tell these should work (and seem to in the playground) but they rely on the second condition being overly strict and the first condition being the one which matters,
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 at the Vec::from_raw_parts documentation linked in the issue and review the context from #95016 and #99216. Reproduce the two Vec conversion examples in the playground, then determine which allocation-size, capacity, and alignment conditions are required. Done means the safety invariants and the status of these conversions are documented without contradiction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100