Macro pin_project_lite::pin_project[][src]

macro_rules! pin_project {
    ($($tt:tt)*) => { ... };
}

A macro that creates a projection type covering all the fields of struct.

This macro creates a projection type according to the following rules:

  • For the field that uses #[pin] attribute, makes the pinned reference to the field.
  • For the other fields, makes the unpinned reference to the field.

And the following methods are implemented on the original type:

fn project(self: Pin<&mut Self>) -> Projection<'_>;
fn project_ref(self: Pin<&Self>) -> ProjectionRef<'_>;

The visibility of the projected type and projection method is based on the original type. However, if the visibility of the original type is pub, the visibility of the projected type and the projection method is pub(crate).

Safety

pin_project! macro guarantees safety in much the same way as pin-project crate. Both are completely safe unless you write other unsafe code.

See pin-project crate for more details.

Examples

use std::pin::Pin;

use pin_project_lite::pin_project;

pin_project! {
    struct Struct<T, U> {
        #[pin]
        pinned: T,
        unpinned: U,
    }
}

impl<T, U> Struct<T, U> {
    fn method(self: Pin<&mut Self>) {
        let this = self.project();
        let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
        let _: &mut U = this.unpinned; // Normal reference to the field
    }
}

If you want to call the project() method multiple times or later use the original Pin type, it needs to use .as_mut() to avoid consuming the Pin.

use std::pin::Pin;

use pin_project_lite::pin_project;

pin_project! {
    struct Struct<T> {
        #[pin]
        field: T,
    }
}

impl<T> Struct<T> {
    fn call_project_twice(mut self: Pin<&mut Self>) {
        // `project` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
        self.as_mut().project();
        self.as_mut().project();
    }
}

!Unpin

If you want to ensure that Unpin is not implemented, use #[pin] attribute for a PhantomPinned field.

use std::marker::PhantomPinned;

use pin_project_lite::pin_project;

pin_project! {
    struct Struct<T> {
        field: T,
        #[pin] // <------ This `#[pin]` is required to make `Struct` to `!Unpin`.
        _pin: PhantomPinned,
    }
}

Note that using PhantomPinned without #[pin] attribute has no effect.