-
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
Consider replacing RawVec<T> with Box<[MaybeUninit<T>]>. #54470
Comments
Seems like it would not fulfill the use cases of RawVec if it doesn't track the capacity. Could be interesting to change RawVec to use |
It tracks the capacity but calls it |
I guess I misunderstood eddy's comment about manipulating the length, he means the length tracked in |
What I meant was the "length" of |
@eddyb why would you have a (I would classify it as an invalid slice, anyways, and therefore UB to value-convert) |
We can probably replace RawVec’s pointer and capacity fields, but its methods still contain a bunch of code that need to live somewhere so it seems unlikely that we’d remove the type entirely. |
|
I think that would be sound, but would it be useful? |
The value of this seems dubious, considering (iirc) RawVec needs to have two "notions" of capacity (stored vs effective) to make it easier to work with ZSTs, and the whole thing would make code a bit more unclear. |
Reopened because of renewed interest: |
See #94421 (comment) for some of the fall-out of doing this: by using Maybe there is a way to have weaker aliasing guarantees for |
As @RalfJung asked me to continue the discussion over here, let me just copy #94421 (comment). Sorry for chiming in. I certainly lack the expertise to understand the intricacies of the ongoing debate but @SabrinaJewson just opened an issue for one of my crates which would be affected by this PR. I just wanted to let you know that I was under the impression that
of the Guarantees section with the previous description of the memory layout makes it seem as if references are guaranteed to be stable when pushing onto a |
Thanks. :) I tend to agree -- I think we have to keep this code working: fn main() {
let mut v = Vec::with_capacity(2);
v.push(0);
let ptr = &v[0] as *const i32;
v.push(0);
unsafe { dbg!(*ptr) };
} The question then is whether we weaken |
I know little about how the aliasing rules work. However, I would be fine with How do the noalias rules interact with things like let Foo { x, y } = &mut foo; Maybe I'm wrong, but I vaguely remember that destructuring to be magic in splitting the mut references. I would consider the boxed slices to have that same treatment where each individual field can exist separately |
If you use It's not really magic, you can do the same with let x = &mut foo.x;
let y = &mut foo.y; |
Ideally then, our slice solution would work such that let x = &mut foo[0];
let y = &mut foo[1]; Is also valid. This is obviously harder though since the IndexMut trait takes the entire |
For primitive slice accesses ( But there is a function indirection, and that breaks it. Allowing it with a function indirection might be possible but would likely mean that all functions can be optimized less. That is the discussion at rust-lang/unsafe-code-guidelines#133. |
It's relatively common for people to say "oh, you can use So I don't know what the best solution would be, but I do think they should be consistent. |
After #53508 lands, we could look into this. It might provide a bit more type-safety, although it could be worse to not have the capacity as a separate field.
One thing to note is that setting the "length" component of a reference/pointer to(please ignore, I managed to confuse myself)[MaybeUninit<T>]
is "less unsafe" than doing so for for[T]
, but it's unclear to me whether having a&[MaybeUninit<T>]
that's larger than the object it points to, is UB or not.cc @RalfJung @gankro @rust-lang/libs
The text was updated successfully, but these errors were encountered: