Based on rust-lang/unsafe-code-guidelines#148 (comment)
by @CAD97
Currently, the generated 'project' method takes a 'Pin<&mut Self>',
consuming it. This makes it impossible to use the original Pin<&mut Self>
after calling project(), since the 'Pin<&mut Self>' has been moved into
the the 'Project' method.
This makes it impossible to implement useful pattern when working with
enums:
```rust
enum Foo {
Variant1(#[pin] SomeFuture),
Variant2(OtherType)
}
fn process(foo: Pin<&mut Foo>) {
match foo.project() {
__FooProjection(fut) => {
fut.poll();
let new_foo: Foo = ...;
foo.set(new_foo);
},
_ => {}
}
}
```
This pattern is common when implementing a Future combinator - an inner
future is polled, and then the containing enum is changed to a new
variant. However, as soon as 'project()' is called, it becoms imposible
to call 'set' on the original 'Pin<&mut Self>'.
To support this pattern, this commit changes the 'project' method to
take a '&mut Pin<&mut Self>'. The projection types works exactly as
before - however, creating it no longer requires consuming the original
'Pin<&mut Self>'
Unfortunately, current limitations of Rust prevent us from simply
modifiying the signature of the 'project' method in the inherent impl
of the projection type. While using 'Pin<&mut Self>' as a receiver is
supported on stable rust, using '&mut Pin<&mut Self>' as a receiver
requires the unstable `#![feature(arbitrary_self_types)]`
For compatibility with stable Rust, we instead dynamically define a new
trait, '__{Type}ProjectionTrait', where {Type} is the name of the type
with the `#[pin_project]` attribute.
This trait looks like this:
```rust
trait __FooProjectionTrait {
fn project(&'a mut self) -> __FooProjection<'a>;
}
```
It is then implemented for `Pin<&mut {Type}>`. This allows the `project`
method to be invoked on `&mut Pin<&mut {Type}>`, which is what we want.
If Generic Associated Types (rust-lang/rust#44265)
were implemented and stablized, we could use a single trait for all pin
projections:
```rust
trait Projectable {
type Projection<'a>;
fn project(&'a mut self) -> Self::Projection<'a>;
}
```
However, Generic Associated Types are not even implemented on nightly
yet, so we need for generate a new trait per type for the forseeable
future.