Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation error in with_capacity family of methods #95614

Closed
jmaargh opened this issue Apr 3, 2022 · 3 comments · Fixed by #96173
Closed

Documentation error in with_capacity family of methods #95614

jmaargh opened this issue Apr 3, 2022 · 3 comments · Fixed by #96173
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools

Comments

@jmaargh
Copy link
Contributor

jmaargh commented Apr 3, 2022

As discussed here, methods like Vec::with_capacity are guaranteed to create a container with at least the specified capacity, but are allowed to allocate more.

The easiest way to see this is with zero-sized types, since no allocation is necessary and capacity is always usize::MAX (I assume).

However, the documentation states "Constructs a new, empty Vec<T> with the specified capacity. The vector will be able to hold exactly capacity elements without reallocating." This is wrong, especially so with the use of the word "exactly". I've picked on Vec::with_capacity here, but all of the other standard library with_capacity and with_capacity_in methods I've checked have the same issue.

Obviously the case of zero-sized types is a trivial example, but this is a safety issue if you're breaking containers into raw parts (e.g. for FFI) and then reconstructing them. For example the following is not sound, but the documentation says it is:

const CAPACITY: usize = 123;
let mut cstr = Vec::<u8>::with_capacity(CAPACITY);
let ptr = cstr.as_mut_ptr();
let mut length = 0;
std::mem::forget(cstr);

let returned_string = unsafe {
  ffi_that_fills_the_string(CAPACITY, &mut length, ptr);
  Vec::from_raw_parts(ptr, length, CAPACITY);
}

let returned_string = String::from_utf8(returned_string)?;

Since the allocator is allowed to allocate more than CAPACITY, making the call to from_raw_parts unsound.

The documentation for reserve and reserve_exact on the other hand are accurate (though I'm not sure why reserve_exact exists, or certainly why it has that name, if it can't guarantee exact allocation).

@GuillaumeGomez GuillaumeGomez added the A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools label Apr 9, 2022
@GuillaumeGomez
Copy link
Member

Interested into sending a fix maybe? Don't hesitate to ask if you need help.

@jmaargh
Copy link
Contributor Author

jmaargh commented Apr 9, 2022

@GuillaumeGomez I'm happy to submit a PR to fix, just wanted to check that I wasn't missing something obvious before I put in the effort

@GuillaumeGomez
Copy link
Member

Not that I could see at least.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jun 23, 2022
…ix, r=Dylan-DPC

Fix documentation for  `with_capacity` and `reserve` families of methods

Fixes rust-lang#95614

Documentation for the following methods
 - `with_capacity`
 - `with_capacity_in`
 - `with_capacity_and_hasher`
 - `reserve`
 - `reserve_exact`
 - `try_reserve`
 - `try_reserve_exact`

was inconsistent and often not entirely correct where they existed on the following types
- `Vec`
- `VecDeque`
- `String`
- `OsString`
- `PathBuf`
- `BinaryHeap`
- `HashSet`
- `HashMap`
- `BufWriter`
- `LineWriter`

since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked `BufReader`, but there the docs appear to be accurate as it appears to actually allocate the exact capacity).

Some effort was made to make the documentation more consistent between types as well.
compiler-errors added a commit to compiler-errors/rust that referenced this issue Jun 23, 2022
…ix, r=Dylan-DPC

Fix documentation for  `with_capacity` and `reserve` families of methods

Fixes rust-lang#95614

Documentation for the following methods
 - `with_capacity`
 - `with_capacity_in`
 - `with_capacity_and_hasher`
 - `reserve`
 - `reserve_exact`
 - `try_reserve`
 - `try_reserve_exact`

was inconsistent and often not entirely correct where they existed on the following types
- `Vec`
- `VecDeque`
- `String`
- `OsString`
- `PathBuf`
- `BinaryHeap`
- `HashSet`
- `HashMap`
- `BufWriter`
- `LineWriter`

since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked `BufReader`, but there the docs appear to be accurate as it appears to actually allocate the exact capacity).

Some effort was made to make the documentation more consistent between types as well.
@bors bors closed this as completed in 262382f Jun 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-docs Area: documentation for any part of the project, including the compiler, standard library, and tools
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants