Skip to content

Vec::with_capacity does not work correctly for zero-sized types #43490

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

Closed
mistodon opened this issue Jul 26, 2017 · 7 comments
Closed

Vec::with_capacity does not work correctly for zero-sized types #43490

mistodon opened this issue Jul 26, 2017 · 7 comments
Labels
A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools C-bug Category: This is a bug. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@mistodon
Copy link

Calling Vec::with_capacity(N) does not give you a vector with capacity N.

fn main()
{
    let v: Vec<()> = Vec::with_capacity(5);
    assert_eq!(v.capacity(), 5);
}

This fails with:

thread 'main' panicked at 'assertion failed: `(left == right)` (left: `18446744073709551615`, right: `5`)', src/main.rs:4

when running in the playground on stable.

I would expect the capacity to be 5. Logically, I realize the capacity for a zero-sized type is not actually limited, but the docs do say "vec![x; n], vec![a, b, c, d], and Vec::with_capacity(n), will all produce a Vec with exactly the requested capacity."

@cuviper
Copy link
Member

cuviper commented Jul 26, 2017

This is a consequence of RawVec::cap which explicitly returns usize::MAX for zero-sized types.
And Vec::capacity says "the number of elements the vector can hold without reallocating," which for ZSTs is simply as many as we can count.

Vec::with_capacity says, "The vector will be able to hold exactly capacity elements without reallocating." I guess you could argue whether that "exactly" implies that it will reallocate for a greater number of elements, but there's never any allocation for ZSTs anyway.

IMO the behavior is fine, but the docs could clarify this situation.

@Mark-Simulacrum Mark-Simulacrum added C-bug Category: This is a bug. I-needs-decision Issue: In need of a decision. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. A-docs Area: Documentation for any part of the project, including the compiler, standard library, and tools labels Jul 26, 2017
@steveklabnik
Copy link
Member

I'm happy to modify the docs but would like to know what the libs team thinks.

@alexcrichton
Copy link
Member

IIRC with_capacity is not guaranteed to return a vector with exactly that capacity, it's allowed to round up also due to the allocator giving it more memory (or something like that). I think this is just a case where the docs may be able to be more explicit.

@sfackler
Copy link
Member

There is reserve_exact, though. Does that handle ZST capacity differently?

@scottmcm
Copy link
Member

Even reserve_exact doesn't guarantee exactly:

Note that the allocator may give the collection more space than it requests. Therefore capacity can not be relied upon to be precisely minimal.

This is essentially that situation -- the "nop allocator" said we can hold lots -- so it feels to me like with_capacity should get the same caveat (also seen on shrink_to_fit).

@dtolnay dtolnay removed the I-needs-decision Issue: In need of a decision. label Sep 11, 2017
@dtolnay
Copy link
Member

dtolnay commented Sep 11, 2017

The behavior is fine. The docs need to indicate that the capacity will be at least what you requested, with the caveat from reserve_exact.

@steveklabnik
Copy link
Member

I'm not sure when this was fixed, but it was:

The collection may reserve more space to avoid frequent reallocations. After calling reserve, capacity will be greater than or equal to self.len() + additional.

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 C-bug Category: This is a bug. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants