I know that when a type implements !Unpin, it can still be moved before being pinned for the first time, like a future before it is ever polled. Is it possible to do the opposite, i.e. transition a self-referential object into a state where there are no more self-references and then move it again? Reading the documentation for Pin::into_inner_unchecked gives me the impression that it's illegal to do so even if the object is in a state where it can be moved without invalidating any references (i.e. when you have full ownership and when there are no self-references).
Am I missing something here or is this intentional? I can always work around it by aping C++-style move semantics (moving doesn't destroy the original, it just leaves a valid but empty object in place, which would remain pinned), but that is rather unsatisfying IMO.
It's entirely possible that a type that doesn't implement Unpin still provides some API for transitioning from pinned to non-pinned, so e. g. Pin<Box<Self>>) -> Box<Self>. Just as someone implementing a type can choose to implement Unpin, they could choose to offer such a function, there's no safety problems with that.
The documentation of Pin::into_inner_unchecked assumes that you're handling some type Pin<P> where you aren't having any additional information on the P::Target type. Often, this might trivially be the case when that target type is just a generic parameter. On the other hand, for example if P::Target is known to be some concrete type and you're the author of that type (or the author of the type gave you some additional guarantees that allow it under certain circumstances), moving the type after it was pinned can be fine.
fn pack_mut<T: PackPinned>(x: Pin<&mut T>)-> &mut T
by calling pack_pinned on the contained value first before moving / exposing it. The unsafe trait would need to be documented with some safety conditions that make sure that these helper functions are sound.
The naming of all of these is probably suboptimal, I'm focusing on the type signatures here