This. I see no difference between let pin foo = …;
and let foo = pin!(…);
, but for the former to be more restrictive than pin!()
which can be inlined within a function call. pin!()
is the counterpart of Box::pin
, which also elegantly ties it back up to this Anchor
/ Pin
historical debut. While pin
-as-a-keyword could be useful as a more general tool (mainly: pin
ning projections, but those would require Unpin
lack of unsafe
to be fixed), until then I don't think saving an exclamation mark warrants adding a dedicated keyword.
Speaking of which, it would be nice if there could be some movement over:
Regarding the OP, their invention is basically &own
, which can be quite useful independently of pin
ning, and there is no &own
counter-part of Box::pin
since a &own
, contrary to a Box
, borrows the backing storage, and thus cannot enforce the pinning guarantee.
FWIW, there is an interesting variant that that exploits "maximal self-lifetime" to almost reach the desired effect:
use ::core::pin::Pin;
struct PinnableSlot<'r, T> {
value: T,
_invariant_lt: ::core::marker::PhantomData<&'r mut &'r ()>,
}
impl<'r, T> PinnableSlot<'r, T> {
// maximally-long `&mut` borrow
// vv vv
fn pinned(self: &'r mut PinnableSlot<'r, T>)
-> Pin<&'r mut T>
{
unsafe { Pin::new_unchecked(&mut self.value) }
}
}
Usage being:
let mut slot = PinnableSlot::new(…);
let thing: Pin<&mut …> = slot.pinned(); // `&mut` is maximal thanks to lifetimes;
// effectively "pinning" it.
Alas, this does not work due to ManuallyDrop
:
let slot = PinnableSlot::new(…);
let mut slot_without_drop = ManuallyDrop::new(slot);
let thing: Pin<&mut …> = slot_without_drop.pinned(); // Uh-oh