moveit::move_ref

Trait AsMove

Source
pub trait AsMove: Deref + Sized {
    type Storage: Sized;

    // Required method
    fn as_move<'frame>(
        self,
        storage: DroppingSlot<'frame, Self::Storage>,
    ) -> Pin<MoveRef<'frame, Self::Target>>
       where Self: 'frame;
}
Expand description

A trait for getting a pinned MoveRef for some pointer type Self.

Conceptually, this trait is similar to DerefMove, except that where DerefMove::deref_move produces a MoveRef<T>, AsMove::as_move produces a Pin<MoveRef<T>>.

DerefMove can be seen as a refinement of AsMove where stronger guarantees about the memory behavior (specifically the Pin-safety) of Self are present.

Codifying this notion is the fact that DerefMove requires that Self: DerefMut + AsMove, whereas AsMove only requires the weaker constraints of Self: Deref.

Although AsMove is a supertrait of DerefMove, but DerefMove is not a supertrait of AsMove, the two traits are nevertheless intended to have their impls for a given type defined together simultanteously.

It is expected in this situation that the impl for one of the traits will be (trivially) defined in terms of the other, depending on the API for the pointer type Self with respect to DerefMut.

For example, the Box<T>: AsMove impl is defined in terms of the Box<T>: DerefMove impl, because it is always the case that Box<T>: DerefMut regardless of whether T: Unpin. Hence, Box<T>: AsMove simply performs the Box<T>: DerefMove operation then subsequently (and trivially) pins the resulting MoveRef<T> with MoveRef::into_pin.

On the other hand, the cxx::UniquePtr<T>: DerefMove impl is defined in terms of the UniquePtr<T>: AsMove impl, because a cxx::UniquePtr<T>: DerefMut only if T: Unpin. Given that cxx::UniquePtr<T> behaves like Pin<Box<T>> with respect to DerefMut, it is always possible to safely produce a Pin<MoveRef<T>>, but not always possible to safely produce a MoveRef<T>. Hence, when T: Unpin, only then cxx::UniquePtr<T>: DerefMove is defined, which simply performs the cxx::UniquePtr<T>: AsMove operation then subsequently (and trivially) unpins the resulting Pin<MoveRef<T>> with Pin::into_inner.

Required Associated Types§

Source

type Storage: Sized

The “pure storage” form of Self, which owns the storage but not the pointee.

Required Methods§

Source

fn as_move<'frame>( self, storage: DroppingSlot<'frame, Self::Storage>, ) -> Pin<MoveRef<'frame, Self::Target>>
where Self: 'frame,

Gets a pinned MoveRef out of Self.

This function is best paired with moveit!():

let ptr = Box::pin(5);
moveit::slot!(#[dropping] storage);
ptr.as_move(storage);

Taking a trip through moveit!() is unavoidable due to the nature of MoveRef.

Compare with Pin::as_mut().

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl<P: DerefMove> AsMove for Pin<P>

Source§

type Storage = <P as AsMove>::Storage

Source§

fn as_move<'frame>( self, storage: DroppingSlot<'frame, Self::Storage>, ) -> Pin<MoveRef<'frame, Self::Target>>
where Self: 'frame,

Source§

impl<T> AsMove for UniquePtr<T>

Source§

type Storage = DeallocateSpaceGuard<T>

Source§

fn as_move<'frame>( self, storage: DroppingSlot<'frame, Self::Storage>, ) -> Pin<MoveRef<'frame, Self::Target>>
where Self: 'frame,

Source§

impl<T> AsMove for Box<T>

Source§

type Storage = Box<MaybeUninit<T>>

Source§

fn as_move<'frame>( self, storage: DroppingSlot<'frame, Self::Storage>, ) -> Pin<MoveRef<'frame, Self::Target>>
where Self: 'frame,

Implementors§

Source§

impl<'f, T: ?Sized> AsMove for MoveRef<'f, T>