Attribute Macro pin_project::project

source · []
#[project]
Expand description

(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 std::pin::Pin;

use pin_project::{pin_project, project};

#[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 std::pin::Pin;

use pin_project::{pin_project, project};

#[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 std::pin::Pin;

use pin_project::{pin_project, project};

#[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 std::pin::Pin;

    use pin_project::project;

    use super::Foo;
    #[project]
    use super::Foo;

    #[project]
    fn baz<A>(foo: Pin<&mut Foo<A>>) {
        #[project]
        let Foo { field } = foo.project();
        let _: Pin<&mut A> = field;
    }
}