-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Add Clone-less converter from Arc to Vec #89215
Add Clone-less converter from Arc to Vec #89215
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
Isn't this a bit limited if it works only for Also, shouldn't |
Very likely. It's simply that I had the implementation for
You're probably right. I did paint myself into a bit of a corner with the idea of possibly having a zero-allocation conversion by moving the elements to overwrite the Another idea—although with significant additional API surface—would be to make a concrete new type |
Maybe in the first step I will reduce this PR to |
This feels very niche. For this to work I think you would need:
|
Okay, we don't need to venture into that niche. So which direction seems most promising to you:
|
I just realize that this isn't really feasible. Doing so would require allocating a place with the correct layout and then duplicating the pointer meta data, in the process of which we are asserting that it is valid to do so and that this produces a pointer that is valid to dereference. That's true for the existing fat pointers (slice, dyn) but I don't think it's been fully discussed. I don't feel comfortable at all with adding a new allocation method to |
In my opinion this leaks more implementation details than necessary. For example currently there's no public concept of an "owning
Adding a new type for the sake of this PR seems overkill to me.
This is already done in the opposite direction by the implementation of
You can use |
4a52be2
to
d171a37
Compare
I've adjusted everything according to our conversation.
Maybe, however I don't fancy contributing to the proliferation of
To learn about those pointer operations being allowed through this channel makes me uncomfortable 😬 Anyways, then that concern of course disappears. |
This comment has been minimized.
This comment has been minimized.
d171a37
to
4ef5f32
Compare
This comment has been minimized.
This comment has been minimized.
Adds methods try_unwrap_as_box that work similar to try_unwrap but instead of reading the value, they move it a separate allocation. This allows unwrapping unsized values as well. By extension this can be used for converting in a vector of slices.
4ef5f32
to
7e0034b
Compare
Okay, I had messed up the combination between |
Can you update the PR description/title with a summary of the current state of this PR? As far as I can tell, the proposal is no longer to add the Arc -> Vec conversion, but rather something different. It looks like this is now adding an API for converting In particular, a "userspace" library could be written that verifies the passed Arc is unique (via get_mut) when taking ownership of it and then provides &T and &mut T access with no overhead, via the Deref and get_mut_unchecked APIs on the internal Arc. That would require a little unsafe code, but nothing all that interesting. |
I'm not OP, but I followed the evolution of this PR, and:
It kinda depends with what you mean with "copy". There's a memcpy, but it's not a
There are two differences between the PR proposal and yours:
|
It's an inverse of the existing
No. There is no way for a userspace library to emulate atomically performing the last CAS (1, 0) on the strong count other than |
I've updated the description to reflect the changes to the code and some parts of the discussionl |
☔ The latest upstream changes (presumably #90067) made this pull request unmergeable. Please resolve the merge conflicts. |
Ping from triage: |
Ping from triage: I'm closing this one due to inactivity, please feel to reopen when you are ready to continue with this. @rustbot label: +S-inactive |
Adds a new converter to
Arc<T: ?Sized>
:try_unwrap_as_box(self) -> Result<Box<T>, Self>
and its counterpart
Rc<T: ?Sized>
:try_unwrap_as_box(self) -> Result<Box<T>, Self>
This method is a safe encapsulation when one wants to extract the (unsized) items behind an
Arc
into an owned allocation. For example, after a computation phase where a slice of items had been shared with workers. None of the existing methods allow taking ownership of an unsized pointee. The only current alternatives are downcasting to a concrete sized types, or in that specific case of a slice a more expensive cloning of the entire slice which requires an additional bound and might invoke arbitrary code.Alternatives:
leak_as_owning_weak
is the 'necessary' operation for performing this in 'userspace'. Concretely, it contains the minimal code around theCAS(1, 0)
that moves ownership of the strong count to the caller. It's been factored out as a shared pattern betweentry_unwrap
and the new interface. It could in theory be used by non-std code to perform the same operations or even different ones if it were madepub
.For example user code might provide
Deref<T>
andDerefMut<T>
in-place by keeping theWeak
. This requires a proper newtype that also could be added to std but is another non-trivial addition, I suppose. That pattern alone does not solve moving the pointee to a properly ownedBox
though.