[][src]Attribute Macro pin_project_internal::project

#[project]

An attribute to provide way to refer to the projected type.

This attribute is available if pin-project is built with the "project_attr" feature.

The following three syntaxes are supported.

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(mut 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;
    }
}

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(mut 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::{project, pin_project};
use std::pin::Pin;

#[pin_project]
enum Foo<A, B, C> {
    Tuple(#[pin] A, B),
    Struct { field: C },
    Unit,
}

impl<A, B, C> Foo<A, B, C> {
    #[project] // Nightly does not need a dummy attribute to the function.
    fn baz(mut self: Pin<&mut Self>) {
        #[project]
        match self.project() {
            Foo::Tuple(x, y) => {
                let _: Pin<&mut A> = x;
                let _: &mut B = y;
            }
            Foo::Struct { field } => {
                let _: &mut C = field;
            }
            Foo::Unit => {}
        }
    }
}