error[E0382]: borrow of moved value: `b1` --> src\self_ref.rs:13:30 | 12 | letb1 = B; | -- move occurs because `b1` has type `B`, which does not implement the `Copy` trait 13 | letet = A{ b: b1, refb: &b1 }; | -- ^^^ value borrowed here after move | | | value moved here
Similarly, Pin<&mut T> is a lot like &mut T. However, Pin<P> does not let clients actually obtain a Box<T> or &mut T to pinned data, which implies that you cannot use operations such as mem::swap
impl<P: Deref<Target: Unpin>> Pin<P> { /// Construct a new `Pin<P>` around a pointer to some data of a type that /// implements [`Unpin`]. /// /// Unlike `Pin::new_unchecked`, this method is safe because the pointer /// `P` dereferences to an [`Unpin`] type, which cancels the pinning guarantees. pubconstfnnew(pointer: P) -> Pin<P> { // SAFETY: the value pointed to is `Unpin`, and so has no requirements // around pinning. unsafe { Pin::new_unchecked(pointer) } }
/// Unwraps this `Pin<P>` returning the underlying pointer. /// /// This requires that the data inside this `Pin` is [`Unpin`] so that we /// can ignore the pinning invariants when unwrapping it. pubconstfninto_inner(pin: Pin<P>) -> P { pin.pointer } }
// We rely on the fact that async/await futures are immovable in order to create // self-referential borrows in the underlying generator. impl<T: Generator<ResumeTy, Yield = ()>> !Unpin forGenFuture<T> {}
impl<T: Generator<ResumeTy, Yield = ()>> Future forGenFuture<T> { typeOutput = T::Return; fnpoll(self: Pin<&mutSelf>, cx: &mut Context<'_>) -> Poll<Self::Output> { // SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection. letgen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
// Resume the generator, turning the `&mut Context` into a `NonNull` raw pointer. The // `.await` lowering will safely cast that back to a `&mut Context`. match gen.resume(ResumeTy(NonNull::from(cx).cast::<Context<'static>>())) { GeneratorState::Yielded(()) => Poll::Pending, GeneratorState::Complete(x) => Poll::Ready(x), } } }