[−][src]Macro pin_project_lite::pin_project
macro_rules! pin_project { ( $(#[$attrs:meta])* pub struct $ident:ident $(< $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)? $( $generics:ident $(: $generics_bound:path)? $(: ?$generics_unsized_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),* $(,)? >)? $(where $($where_clause_ty:ty : $where_clause_bound:path),* $(,)? )? { $( $(#[$pin:ident])? $field_vis:vis $field:ident: $field_ty:ty ),+ $(,)? } ) => { ... }; ( $(#[$attrs:meta])* $vis:vis struct $ident:ident $(< $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* $(,)? $( $generics:ident $(: $generics_bound:path)? $(: ?$generics_unsized_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),* $(,)? >)? $(where $($where_clause_ty:ty : $where_clause_bound:path),* $(,)? )? { $( $(#[$pin:ident])? $field_vis:vis $field:ident: $field_ty:ty ),+ $(,)? } ) => { ... }; (@internal ($proj_vis:vis) // limitation: does not support tuple structs and enums (wontfix) // limitation: no projection helper (wontfix) $(#[$attrs:meta])* $vis:vis struct $ident:ident $(< $( $lifetime:lifetime $(: $lifetime_bound:lifetime)? ),* // limitation: does not support multiple trait/lifetime bounds and ? trait bounds. $( $generics:ident $(: $generics_bound:path)? $(: ?$generics_unsized_bound:path)? $(: $generics_lifetime_bound:lifetime)? $(= $generics_default:ty)? ),* >)? $(where // limitation: does not support multiple trait/lifetime bounds and ? trait bounds. $($where_clause_ty:ty : $where_clause_bound:path),* )? { $( // limitation: cannot interoperate with other attributes. $(#[$pin:ident])? $field_vis:vis $field:ident: $field_ty:ty ),+ } ) => { ... }; (@make_unpin_bound #[pin] $field_ty:ty ) => { ... }; (@make_unpin_bound $field_ty:ty ) => { ... }; (@make_unsafe_field_proj $this:ident; #[pin] $field:ident; $($mut:ident)? ) => { ... }; (@make_unsafe_field_proj $this:ident; $field:ident; $($mut:ident)? ) => { ... }; (@make_proj_field #[pin] $field_ty:ty; $($mut:ident)? ) => { ... }; (@make_proj_field $field_ty:ty; $($mut:ident)? ) => { ... }; }
A macro that creates a projection struct covering all the fields.
This macro creates a projection struct 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.
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)
.
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
.
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 pin_project_lite::pin_project; use std::pin::Pin; pin_project! { struct Struct<T, U> { #[pin] pinned: T, unpinned: U, } } impl<T, U> Struct<T, U> { fn foo(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 } }
Note that borrowing the field where #[pin]
attribute is used multiple
times requires using .as_mut()
to avoid
consuming the Pin
.