[−][src]Attribute Macro pin_project::project
#[project]
An attribute to provide way to refer to the projected type returned by
project
method.
The following syntaxes are supported.
let
bindings
The attribute at the expression position is not stable, so you need to use
a dummy #[project]
attribute for the function.
Examples
use pin_project::{pin_project, project}; use std::pin::Pin; #[pin_project] struct Foo<T, U> { #[pin] future: T, field: U, } impl<T, U> Foo<T, U> { #[project] // Nightly does not need a dummy attribute to the function. fn baz(self: Pin<&mut Self>) { #[project] let Foo { future, field } = self.project(); let _: Pin<&mut T> = future; let _: &mut U = field; } }
match
expressions
The attribute at the expression position is not stable, so you need to use
a dummy #[project]
attribute for the function.
Examples
use pin_project::{pin_project, project}; use std::pin::Pin; #[pin_project] enum Enum<A, B, C> { Tuple(#[pin] A, B), Struct { field: C }, Unit, } impl<A, B, C> Enum<A, B, C> { #[project] // Nightly does not need a dummy attribute to the function. fn baz(self: Pin<&mut Self>) { #[project] match self.project() { Enum::Tuple(x, y) => { let _: Pin<&mut A> = x; let _: &mut B = y; } Enum::Struct { field } => { let _: &mut C = field; } Enum::Unit => {} } } }
impl
blocks
All methods and associated functions in #[project] impl
block become
methods of the projected type. If you want to implement methods on the
original type, you need to create another (non-#[project]
) impl
block.
To call a method implemented in #[project] impl
block, you need to first
get the projected-type with let this = self.project();
.
Examples
use pin_project::{pin_project, project}; use std::pin::Pin; #[pin_project] struct Foo<T, U> { #[pin] future: T, field: U, } // impl for the original type impl<T, U> Foo<T, U> { fn bar(self: Pin<&mut Self>) { self.project().baz() } } // impl for the projected type #[project] impl<T, U> Foo<T, U> { fn baz(self) { let Self { future, field } = self; let _: Pin<&mut T> = future; let _: &mut U = field; } }
use
statements
Examples
use pin_project::pin_project; #[pin_project] struct Foo<A> { #[pin] field: A, } mod bar { use super::Foo; use pin_project::project; use std::pin::Pin; #[project] use super::Foo; #[project] fn baz<A>(foo: Pin<&mut Foo<A>>) { #[project] let Foo { field } = foo.project(); let _: Pin<&mut A> = field; } }