-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Tracking issue for Weak::into_raw/from_raw & similar #60728
Comments
A PR is sufficient; the motivation can be justified in there. |
Weak::into_raw Hello This is my first shot at rust-lang#60728. I'd like to consult it a bit before moving further. The biggest question I have is if this API makes sense. My motivation for it is to be able to store the `Weak` in `AtomicPtr`. For that I don't actually need for the pointer to point to the `T`, any pointer (maybe casted to `usize`) would be good enough, but this mirrors what `Arc` does and could be useful for other things too (like comparing if Arc and Weak point to the same thing without playing with the counts), while some opaque pointer wouldn't. Some secondary questions, if this is deemed desirable are: * The weak pointer may be dangling if it is created by `Weak::new()`. It would make sense to treat this as NULL, but that is incompatible with `T: ?Sized` ‒ both `new()` and `ptr::null()` are available only for sized types. The current implementation is therefore also available only for sized `T`s. It would be possible to allow `?Sized` if the API would be `fn into_raw(self) -> Option<NonNull<T>>` and `fn from_raw(NonNull<T>)`, but that's different API than `Arc` has. What would be preferred? * There's a FIXME in my code about what I suspect could be UB. Is it really UB & how to get the pointer correctly? Is manual offsetting of the pointer the only way? * Am I missing some other necessary thing around the feature gates and such? * Is the documentation understandable? I know writing docs is not my strongest skill :-|. Thinks I'd like to do as part of the PR, but are not yet done: * Turn the referenced issue into tracking issue for the feature flag. * Once the `sync::Weak` is considered reasonable, I'd do the equivalent for `rc::Weak`. * This might call for few more tests than what is currently part of the documentation.
Weak::into_raw Hello This is my first shot at rust-lang#60728. I'd like to consult it a bit before moving further. The biggest question I have is if this API makes sense. My motivation for it is to be able to store the `Weak` in `AtomicPtr`. For that I don't actually need for the pointer to point to the `T`, any pointer (maybe casted to `usize`) would be good enough, but this mirrors what `Arc` does and could be useful for other things too (like comparing if Arc and Weak point to the same thing without playing with the counts), while some opaque pointer wouldn't. Some secondary questions, if this is deemed desirable are: * The weak pointer may be dangling if it is created by `Weak::new()`. It would make sense to treat this as NULL, but that is incompatible with `T: ?Sized` ‒ both `new()` and `ptr::null()` are available only for sized types. The current implementation is therefore also available only for sized `T`s. It would be possible to allow `?Sized` if the API would be `fn into_raw(self) -> Option<NonNull<T>>` and `fn from_raw(NonNull<T>)`, but that's different API than `Arc` has. What would be preferred? * There's a FIXME in my code about what I suspect could be UB. Is it really UB & how to get the pointer correctly? Is manual offsetting of the pointer the only way? * Am I missing some other necessary thing around the feature gates and such? * Is the documentation understandable? I know writing docs is not my strongest skill :-|. Thinks I'd like to do as part of the PR, but are not yet done: * Turn the referenced issue into tracking issue for the feature flag. * Once the `sync::Weak` is considered reasonable, I'd do the equivalent for `rc::Weak`. * This might call for few more tests than what is currently part of the documentation.
@rust-lang/libs is there any opposition to stabilizing at least |
When you bring it up, what needs to be done for stabilizing it all? The API follows the one on There's the problem with unsized |
Relaxing the restriction of
The safety requirement requires that the pointer point to a valid
As for |
It's been a while since I wrote it, so I went back to have a look. I think it is slightly different than how you describe it. If I read through it correctly, there are three kinds of weak pointer values:
The The code needs to special-case the sentinel value somehow anyway, it can't just add the offset to it, because it would overflow and that is AFAIK forbidden thing to do with pointers. It could also return the sentinel value ( I can try changing the sentinel value and see if I can add support for unsized types instead. As for the documentation, if I just remove all notions of null and keep it to the fact the pointer must come from previous |
Ah, I admit, I read the code wrong. Ok, I agree returning But the nonexistence of I don't know the exact way std would accomplish this, but "all" that needs to be done is to pull the metadata off of the inner pointer, and put it onto a null pointer. (And then do the same thing in For docs, I'd just specify that the pointer given to |
I've tried updating the docs, I hope it's for the better.
It's not the problem with null pointers per se, because But, after clarifying the documentation, is there anything that would prevent adding that specialization/relaxing the bounds in the future in backwards compatible manner? |
Clarify it is OK to pass a pointer that never owned a weak count (one from Weak::new) back into it as it was created from it. Relates to discussion in rust-lang#60728.
…tolnay weak-into-raw: Clarify some details in Safety Clarify it is OK to pass a pointer that never owned a weak count (one from Weak::new) back into it as it was created from it. Relates to discussion in rust-lang#60728. @CAD97 Do you want to have a look at the new docs?
Hello? I know this is probably not a high priority feature, but it also seems somewhat small and I'd really like to push it over the finish line somehow. Is this waiting on something from me? I believe the raised concerns about docs were hopefully addressed. |
@rfcbot fcp merge |
Team member @Amanieu has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
I would prefer if we made no guarantee as to what pointer value is generated for a dangling @rfcbot concern dangling The convention for returning raw pointers to a value is @rfcbot concern |
@Amanieu Consider not only that other types use
I think sticking to There's also the fact that I would think " Some small-ish concerns:
@rfcbot concern api should be mirrored on I want to make sure that these functions on @rfcbot concern forwards-compatible to I don't know if the rfcbot commands will work for me (they probably won't), but might as well try. |
Fair enough, let's leave the semantics of |
While implementing it, I've noticed one thing. The current implementation will return a pointer with invalid alignment. Is that Ok?
Here, as part of this feature? |
I think it's fine to return an unaligned pointer (you're not allowed to dereference it anyways). We should document it however.
Sure, might as well. |
…anieu Address concerns of weak-into-raw This should address the standing concerns in rust-lang#60728 (comment). I've still left the ability to create a new dangling pointer from `null`, as I feel like this is the natural behaviour to expect, but I'm fine removing that too. I've modified the documentation to allow the `as_ptr` or `into_ptr` to return whatever garbage in case of a dangling pointer. I've also removed the guarantee to be able to do `from_raw(as_ptr)` from the documentation (but it would still work right now). I've renamed the method and added implementations for `Rc`/`Arc`. I've also tried if I can just „enable“ unsized types. I believe the current interface is compatible with them. But the inner implementation will be a bit challenging ‒ I can't use the `data_offset` as is used by `Rc` or `Arc` because it AFAIK „touches“ (creates a reference to) the live value of `T` ‒ and in case of `Weak`, it might be completely bogus or already dead ‒ so that would be UB. `./x.py test tidy` is completely mad on my own system all over the code base :-(. I'll just hope it goes through CI, or will fix as necessary. Is it OK if I ask @Amanieu for review, as the concerns are from you? ~r @Amanieu
…anieu Address concerns of weak-into-raw This should address the standing concerns in rust-lang#60728 (comment). I've still left the ability to create a new dangling pointer from `null`, as I feel like this is the natural behaviour to expect, but I'm fine removing that too. I've modified the documentation to allow the `as_ptr` or `into_ptr` to return whatever garbage in case of a dangling pointer. I've also removed the guarantee to be able to do `from_raw(as_ptr)` from the documentation (but it would still work right now). I've renamed the method and added implementations for `Rc`/`Arc`. I've also tried if I can just „enable“ unsized types. I believe the current interface is compatible with them. But the inner implementation will be a bit challenging ‒ I can't use the `data_offset` as is used by `Rc` or `Arc` because it AFAIK „touches“ (creates a reference to) the live value of `T` ‒ and in case of `Weak`, it might be completely bogus or already dead ‒ so that would be UB. `./x.py test tidy` is completely mad on my own system all over the code base :-(. I'll just hope it goes through CI, or will fix as necessary. Is it OK if I ask @Amanieu for review, as the concerns are from you? ~r @Amanieu
May I ask what happens now? I believe I've addressed the concerns and it was merged, but they are still listed here. How are they removed? |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
Hmm, I don't know about that |
@Kixunil Can you explain what you mean? It was renamed to |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
There are other use cases. Like, hashing it, equivalence checking, etc. |
@vorner aren't those cases better served by using a reference and converting it? Seems more obvious what it does. |
What reference do you have in mind? But I don't really understand your issue. What kind of misuse are you afraid of? I assume that when the FPC is over, I can enjoy submitting a stabilization PR. |
Ah, yeah, I missed that. I had strong ones in mind mostly. Might be a good reason to have I was mostly wondering about (Personal experience: code sending a pointer from one thread to another waiting on select over a Unix pipe, the sender forgot to ref the pointer. Took years to find the cause of mysterious crashes.) |
That wouldn't allow customizing how you hash or against what you compare the pointer (I'd say
But that is not true. The pointer is fully usable as long as you make sure by some other means that the lifetime of the object is still valid, same as with any other pointer. |
Yeah, it's possible to do it by other means, I just can't imagine a real-life situation in which one would have a That all being said, it's not a huge deal, I guess. Mainly wanted this to be considered. |
Stabilizes rust-lang#60728.
…tolnay Stabilization of weak-into-raw Closes rust-lang#60728. There are also two removals of `#![feature(weak_into_raw)]` in the `src/tools/miri` submodule. How should I synchronize the changes with there? * I can ignore it for now and once this gets merged, update the tool, send a pull request to that one and then reference the changes to rustc. * I could try submitting the changes to miri first, but then the build would fail there, because the attribute would still be needed. I think the first one is the correct one, extrapolating from the contributing guidelines (even though they speak about breaking the tools and this should not break it, as extra feature should not hurt).
Changing this to a tracking issue for the feature:
Weak::new()
) andT: ?Sized
? These seem to be incompatible.The original proposal
Hello
The Arc has the
into_raw
andfrom_raw
methods. I think it would be technically possible to have the same onWeak
. Obviously, asWeak
is non-owning, it would be up to the caller to make sure the pointer is not dangling when used.Would adding these (and maybe
as_raw
too ‒ one can get a reference out ofArc
, but not fromWeak
) require an RFC, because the handling of these methods might be even a bit more delicate than the ones onArc
, or is this considered small enough for just a pull request & later stabilization?Motivation
I've written the arc-swap crate that allows to keep an Arc around but make it point to some other object atomically. It uses the mentioned methods. It would make sense to have weak version of this atomic storage too.
Additionally, the
as_raw
would make it possible to compare if eg anArc
andWeak
point to the same object (which would also come handy in some alternative of theCache
that doesn't hold the object alive needlessly).The text was updated successfully, but these errors were encountered: