rust
rust copied to clipboard
Tracking Issue for `pin_deref_mut`
Feature gate: #![feature(pin_deref_mut)]
This is a tracking issue for Pin::as_deref_mut.
The feature adds the method as_deref_mut to Pin, which allow a safe transformation from a Pin<&mut Pin<P>> to a Pin<&mut P::Target>.
Public API
impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> {
pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> { /* .. */ }
}
Steps / History
- [x] Implementation: #81363
- [ ] Final comment period (FCP)
- [ ] Stabilization PR
Unresolved Questions
- None yet.
from a
Pin<P>
It's from a Pin<&'a mut Pin<P>>, right? The nesting is a bit odd. But I guess it is what comes up in practice?
Ah, yes, sorry — fixed!
Are there any remaining blockers on this? It's a pretty useful function for blanket impls for traits with poll methods (e.g. Future already uses it in its impl<P> Future for Pin<P> impl).
Not that I know of — given it touches the Pin machinery, I suspect it should go through an actual FCP, but I'll let others be the judge of that :)
Currently this method is located in its own solitary impl block:
impl<'a, Ptr: DerefMut> Pin<&'a mut Pin<Ptr>> {
pub fn as_deref_mut(self) -> Pin<&'a mut Ptr::Target>;
}
I'd like to consider changing it to:
impl<Ptr> Pin<Ptr> {
pub fn as_deref_mut(self: Pin<&mut Pin<Ptr>>) -> Pin<&mut Ptr::Target>
where
Ptr: DerefMut;
}
Some advantages:
- Synergy with the existing
as_refandas_mutsignatures (stable since Rust 1.33) - Lifetime elision reduces noise in the signature
- Turbofish less verbose:
Pin::<&mut T>::as_deref_mutvsPin::<&mut Pin<&mut T>>::as_deref_mut
impl<Ptr> Pin<Ptr> {
pub fn as_ref(&self) -> Pin<&Ptr::Target>
where
Ptr: Deref;
pub fn as_mut(&mut self) -> Pin<&mut Ptr::Target>
where
Ptr: DerefMut;
}
Any concern blocks this from stablization?
@dtolnay I agree — that is better :+1:
Would it be possible to start an FCP on this?
@rust-lang/libs-api: @rfcbot fcp merge
.as_deref_mut() is like .get_mut().as_mut(), but without enforcing an unnecessary Ptr: Unpin.
It is like unsafe { .get_unchecked_mut() }.as_mut(), but is unconditionally safe.
The use case arises in real-world code when you are implementing a trait that takes self: Pin<&mut Self> where the Self type of your impl is Pin<Ptr>. So what you have is something like Pin<&mut Pin<Box<T>>>, and want to delegate to the impl for T which takes Pin<&mut T>. Some examples:
In tokio: impl<P> AsyncRead for Pin<P>
In hyper: impl<P> Read for Pin<P>
In futures: impl<P> Stream for Pin<P>
In actix: impl<P, A> ActorFuture<A> for Pin<P>
In libcore:
https://github.com/rust-lang/rust/blob/bf662eb80838008acabc307dd64d84935ce3a20d/library/core/src/future/future.rs#L116-L122
https://github.com/rust-lang/rust/blob/bf662eb80838008acabc307dd64d84935ce3a20d/library/core/src/async_iter/async_iter.rs#L99-L106
Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:
- [x] @Amanieu
- [x] @BurntSushi
- [x] @dtolnay
- [ ] @joshtriplett
- [ ] @m-ou-se
No concerns currently listed.
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.
:bell: This is now entering its final comment period, as per the review above. :bell:
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.
This will be merged soon.