[][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;
    }
}