-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
RawVec stores a capacity field even if T is zero-sized #45431
Comments
Time to interpret what https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#guarantees actually means for this
Plain reading says that the capacity field must be there. It's a bit silly, since the only interface with the representation should be with |
@bluss I am finishing overhauling the growth-strategy for vectors (#29931, #27627, I'd like to find a mentor to discuss it before submitting a PR) but I'd like to improve on this afterwards. My proposal would be to amend those guarantees as follows:
And then to replace the |
FWIW I think that the standard library should make more guarantees than it currently does, in particular with respect to the space and time complexity of operations. Yet I think this is an example of something that the standard library should never guarantee. The wording kills me:
What is this guarantee for? It sounds like I can rely on this for serialization purposes, but then the Changing this wording would be a breaking change, but if we can't change this, this should become an example of how the types of guarantees that standard library types should not be making. |
Cool. Does it include using usable_size as well? (Don't worry if not, I think that's fine to address as a separate little project too.) I think the guarantees are definitely overreaching there, but since they are not well defined enough to actually be used for much of anything, maybe the whole triplet thing can be reworded — the Vec has a representation equivalent to pointer, capacity and length, it's just that the capacity doesn't need to be stored for some element types. By the way, do RawVec and Vec need to store a pointer field for ZST? For questions, I'll certainly answer anything I can if you find me here or on IRC. Then I suppose @gankro can as well, if he has time. I haven't heard about struct field specialization, and would love to read more about that. |
I agree it could also forgo the pointer. All a ZST Vec should need to store is a length. I guess it only depends on whether |
@cuviper I am talking about |
We can't implement this until some kind of specialization allows it in a backwards compatible way. Aside from doubts about associated type specialization, the problem of keeping Vec covariant in T., Which is not the case with a.t.spec. now AFAIU. |
@bluss can you elaborate about how this kind of specialization would change the variance of |
@gnzlbg Yeah, I was meaning to come back to you with an example. Here's some code that shows that code that compiles for current struct CurrentVec<T> {
elements: Box<T>
}
struct SmartRepresentationVec<T> {
elements: <T as Smart>::Representation,
}
trait Smart {
type Representation;
}
impl<T> Smart for T {
type Representation = Box<T>;
}
// This compiles!
fn change_lifetime1<'a, T>(input: CurrentVec<&'static T>) -> CurrentVec<&'a T> {
input
}
// This does not! The SmartRepresentationVec is invariant in its parameter.
fn change_lifetime2<'a, T>(input: SmartRepresentationVec<&'static T>) -> SmartRepresentationVec<&'a T> {
input
} |
@bluss why is that? |
I don't know exactly why the rule is like this. It looks like niko explains the rule here: #21726 (comment) by showing how the old |
I would like to see an implementation of this in a PR. My reading of the Guarantees section seems like the "no more, no less" claim is just a generalization of the following claims, not a further claim of its own. It just means to say that Vec can't be a rope, can't do small-vector optimization, must support efficient conversion to |
Notice that in rust-lang/unsafe-code-guidelines#224 a different extension is discussed. That is, adding a With this and that optimizations, A way to provide wording that guarantees that these optimizations will never happen would be to, e.g., guarantee that the |
Is there a tangible use case for making Vec smaller for some types? |
As noted in #117763, fixing this could allow giving @rustbot label A-layout A-specialization I-heavy I-slow |
When
std::mem::size_of::<T>() == 0
RawVec<T>
has always a capacity equal tostd::usize::MAX
elements. It currently stores acap: usize
that always contains this value but doing so is unnecessary in this case.@withoutboats this would be a not so far fetched case for allowing
struct
specialization like @arielb1 proposed.The text was updated successfully, but these errors were encountered: