You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I now notice that stack pinning is not part of the RFC, @withoutboats are you planning on releasing a crate for this, or should I just copy the example code into my crate that needs it?
@Nemo157 You should copy it and report your experience!
The unresolved question about leaking Unpin data relates to this. That API is unsound if we say you cannot overwrite Unpin data in a Pin unless the destructor runs, as @cramertj requested. There are other, less ergonomic, stack pinning APIs that do work for this. Its unclear what the right choice here is - is the ergonomic stack pinning API more useful or is the extra guarantee about leaking more useful?
One thing I'll note is that the stack pinning was not sufficient for things like Future::poll inside the await! macro, because it didn't allow us to poll in a loop. I'd be interested if you run into those issues, and how/if you solve them if you do.
One thing I'll note is that the stack pinning was not sufficient for things like Future::poll inside the await! macro, because it didn't allow us to poll in a loop.
@RalfJung Yes, that's correct. However, PinBox can be reborrowed as Pin, while the stack-pinned type cannot (one borrow as Pin creates a borrow for the entire lifetime of the stack type).
Given a Pin, I can borrow it as &mut Pin and then use Pin::borrow -- that's a form of reborrowing. I take it that's not the kind of reborowing you are talking about?
@RalfJung No-- methods like Future::poll were planned to take self: Pin<Self>, rather than self: &mut Pin<Self> (which isn't a valid self type since it isn't Deref<item = Self> -- it's Deref<Item = Pin<Self>>).
So what are the states of the two concerns now? (api-refactor & get_mut_unchecked_mut_mut) As someone who's eagerly waiting for the async/await series feature, I wonder which rustc version will the Pin APIs target? Is there an estimation?
Ok I apologise if this is not the place to post this, but I have been thinking about the Drop + !Unpin issue, and have come out with the following idea:
Ideally, if Drop::drop was fn(self: Pin<&mut Self>) there would be no issue. Let's call such a DropPinDrop. We cannot just replace Drop by PinDrop because of retrocompatibility issues.
since the only issue with Drop::drop(&mut self) is for the Drop + !Unpin case, we could derive a default impl of PinDrop for Drop + Unpin (since then Pin<&mut T> : DerefMut<Target = T>) and make PinDrop be the trait automagically used by rustc (thanks to Pin::new_unchecked(&mut self), since drop is the only case of stack pinning when we think about it).
Anyways, imho this should remain in beta and not go stable yet, even if it has to be an exception. If there is a time where Drop behavior can depend on Unpin without breaking compat then that time is now.
an implicit T: Unpin bound on all generics, with an opt-out using ?Unpin in the same manner as Sized
This has a huge effect on the overall API design, and was discussed extensively as part of the ?Move proposals. For example, it would mean that many, many existing libraries would need updating to work with pinning. The conclusion was that going with a library-only solution such as what we got now is better because it requires none of this.
Yep, huge cost short term since all existing libraries would need to update to be !Unpin compatible, but in the long run we would end up with a "safer" Drop. It did not seem that bad at first, since at least we are not breaking anything.
But it is a fair concern (I did not know that it had been raised previously; thank you for pointing it out, @RalfJung ), and I guess that the short term practical drawbacks do out-weight the little safety gain of a drop(Pin<&mut Self>).
Pin should probably have an implementation of Hash that simply delegates to the contained pointer, there's no precedence for hashing based on addresses (and I don't see any reason that pinning a value should change how it gets hashed).
Reacted by Taylor Cramer, Daniel Henry-Mantilla, Eduard-Mihai Burtescu, tema3210 and Ruben Anders
Activity
Nemo157 commentedon Mar 20, 2018
I now notice that stack pinning is not part of the RFC, @withoutboats are you planning on releasing a crate for this, or should I just copy the example code into my crate that needs it?
withoutboats commentedon Mar 21, 2018
@Nemo157 You should copy it and report your experience!
The unresolved question about leaking
Unpindata relates to this. That API is unsound if we say you cannot overwriteUnpindata in aPinunless the destructor runs, as @cramertj requested. There are other, less ergonomic, stack pinning APIs that do work for this. Its unclear what the right choice here is - is the ergonomic stack pinning API more useful or is the extra guarantee about leaking more useful?One thing I'll note is that the stack pinning was not sufficient for things like
Future::pollinside theawait!macro, because it didn't allow us to poll in a loop. I'd be interested if you run into those issues, and how/if you solve them if you do.Nemo157 commentedon Mar 21, 2018
My current usage is pretty trivial, a single-threaded executor running a single
StableFuturewithout spawning support. Switching to an API like @cramertj suggests would work fine with this. I have wondered how to extend this to allow spawning multipleStableFutures, but at least with my current project that's not necessary.valff commentedon Mar 29, 2018
Just tried to experiment with the API. Looks like the following (suggested by RFC) definition of
Futureis no longer object-safe?valff commentedon Mar 29, 2018
Nevermind. Found a note about a plan to make
arbitrary_self_typesobject-safe.RalfJung commentedon Mar 29, 2018
@withoutboats
Could you elaborate on that?
cramertj commentedon Mar 29, 2018
@RalfJung You need
Pinto support reborrows asPin, which it currently does not.RalfJung commentedon Mar 30, 2018
@cramertj That sounds like a restriction of the
PinAPI, not of the stack pinning API?cramertj commentedon Mar 30, 2018
@RalfJung Yes, that's correct. However,
PinBoxcan be reborrowed asPin, while the stack-pinned type cannot (one borrow asPincreates a borrow for the entire lifetime of the stack type).RalfJung commentedon Mar 30, 2018
Given a
Pin, I can borrow it as&mut Pinand then usePin::borrow-- that's a form of reborrowing. I take it that's not the kind of reborowing you are talking about?cramertj commentedon Mar 30, 2018
@RalfJung No-- methods like
Future::pollwere planned to takeself: Pin<Self>, rather thanself: &mut Pin<Self>(which isn't a validselftype since it isn'tDeref<item = Self>-- it'sDeref<Item = Pin<Self>>).withoutboats commentedon Mar 30, 2018
It might be the case that we could get this to work with
Pin::borrowactually. I'm not sure.218 remaining items
Pauan commentedon Oct 23, 2018
@tikue @tmandry @withoutboats Thanks for the answers! It was very helpful.
crlf0710 commentedon Oct 28, 2018
So what are the states of the two concerns now? (
api-refactor&get_mut_unchecked_mut_mut) As someone who's eagerly waiting for the async/await series feature, I wonder which rustc version will thePinAPIs target? Is there an estimation?aturon commentedon Nov 9, 2018
@crlf0710 see the stabilization proposal.
Auto merge of #55992 - cramertj:pin-docs, r=alexcrichton
Centril commentedon Dec 27, 2018
@withoutboats Seems done? Shall we close?
danielhenrymantilla commentedon Feb 11, 2019
Ok I apologise if this is not the place to post this, but I have been thinking about the
Drop + !Unpinissue, and have come out with the following idea:Ideally, if
Drop::dropwasfn(self: Pin<&mut Self>)there would be no issue. Let's call such aDropPinDrop. We cannot just replaceDropbyPinDropbecause of retrocompatibility issues.since the only issue with
Drop::drop(&mut self)is for theDrop + !Unpincase, we could derive a default impl ofPinDropforDrop + Unpin(since thenPin<&mut T> : DerefMut<Target = T>) and makePinDropbe the trait automagically used byrustc(thanks toPin::new_unchecked(&mut self), since drop is the only case of stack pinning when we think about it).Here is a sketchy PoC of the idea: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9aae40afe732babeafef9dab3d7525a8
Anyways, imho this should remain in
betaand not go stable yet, even if it has to be an exception. If there is a time whereDropbehavior can depend onUnpinwithout breaking compat then that time is now.RalfJung commentedon Feb 11, 2019
@danielhenrymantilla I don't see how that solves the problem of compatibility with existing generic drop impls, like
impl<T> Drop for Vec<T>.danielhenrymantilla commentedon Feb 11, 2019
You're right it requires another thing:
an implicit
T: Unpinbound on all generics, with an opt-out using?Unpinin the same manner asSizedThat should make it become
RalfJung commentedon Feb 11, 2019
This has a huge effect on the overall API design, and was discussed extensively as part of the
?Moveproposals. For example, it would mean that many, many existing libraries would need updating to work with pinning. The conclusion was that going with a library-only solution such as what we got now is better because it requires none of this.danielhenrymantilla commentedon Feb 11, 2019
Yep, huge cost short term since all existing libraries would need to update to be
!Unpincompatible, but in the long run we would end up with a "safer"Drop. It did not seem that bad at first, since at least we are not breaking anything.But it is a fair concern (I did not know that it had been raised previously; thank you for pointing it out, @RalfJung ), and I guess that the short term practical drawbacks do out-weight the little safety gain of a
drop(Pin<&mut Self>).shanemikel commentedon Apr 23, 2019
Has there been any discussion on
Hashimplementation forPintypes hashing on addresses?Nemo157 commentedon Apr 23, 2019
Pinshould probably have an implementation ofHashthat simply delegates to the contained pointer, there's no precedence for hashing based on addresses (and I don't see any reason that pinning a value should change how it gets hashed).