Macro pin_project_lite::pin_project [−][src]
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.