[][src]Attribute Macro pin_project::project

#[project]

(deprecated) An attribute to provide way to refer to the projected type returned by project method.

This attribute is deprecated. Consider naming projected type by passing project argument to #[pin_project] attribute instead, see release note for details

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