Git Product home page Git Product logo

pin-project's Introduction

pin-project

crates.io docs.rs license msrv github actions

A crate for safe and ergonomic pin-projection.

Usage

Add this to your Cargo.toml:

[dependencies]
pin-project = "1"

Examples

#[pin_project] attribute creates projection types covering all the fields of struct or enum.

use std::pin::Pin;

use pin_project::pin_project;

#[pin_project]
struct Struct<T, U> {
    #[pin]
    pinned: T,
    unpinned: U,
}

impl<T, U> Struct<T, U> {
    fn method(self: Pin<&mut Self>) {
        let this = self.project();
        let _: Pin<&mut T> = this.pinned; // Pinned reference to the field
        let _: &mut U = this.unpinned; // Normal reference to the field
    }
}

code like this will be generated

To use #[pin_project] on enums, you need to name the projection type returned from the method.

use std::pin::Pin;

use pin_project::pin_project;

#[pin_project(project = EnumProj)]
enum Enum<T, U> {
    Pinned(#[pin] T),
    Unpinned(U),
}

impl<T, U> Enum<T, U> {
    fn method(self: Pin<&mut Self>) {
        match self.project() {
            EnumProj::Pinned(x) => {
                let _: Pin<&mut T> = x;
            }
            EnumProj::Unpinned(y) => {
                let _: &mut U = y;
            }
        }
    }
}

code like this will be generated

See #[pin_project] attribute for more details, and see examples directory for more examples and generated code.

Related Projects

  • pin-project-lite: A lightweight version of pin-project written with declarative macros.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

pin-project's People

Contributors

aaron1011 avatar alecmocatta avatar avranju avatar bors[bot] avatar daxpedda avatar diggsey avatar dnaka91 avatar matheus-consoli avatar oxalica avatar ralfjung avatar robjtede avatar taiki-e avatar vojtechkral avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pin-project's Issues

Provide a way to guarantee the type is !Unpin

UPDATE: see #108 (comment).

As mentioned in #102, it seems difficult to guarantee this with stable rust at this time.

However, I think it would be preferable if an option like #[pin_project(!Unpin)] could be provided in the future.

Some ways have been mentioned in #102, but it needs to work correctly for generics and conditional implementations in order to use with pin-project.

Remove "project_attr" feature and always enable #[project] attribute

This feature is now much more convenient than it was when it was introduced. This is necessary when using enums and will be more convenient if #85 and #81 are merged. I feel that it may make sense to enable it by default.

Also, one of the reasons why this is an optional feature was that it had some bugs, but I think most of these were fixed in #38 and #52. So, if we enable it by default, we can also remove the feature gate.

Provide way to import projection trait

The current project/project_into methods are trait-methods, so it needs to use glob import to use it from other modules.

We could probably provide the following way:

#[pin_project]
struct Foo<T> {
    #[pin]
    field: T,
}
mod bar {
    #[project]
    use super::Foo;
    // convert to
    use super::__FooProjectionTrait;
}

Add master 'ci.sh'

Currently, pin-project runs several different checks on Azure pipelines, from a standard cargo test to a compiletest-rs test to clippy. It can be very easy to forgot to one run of these locally, or to run one with the incorrect flag (e.g. missing --all).

It would be very helpful if pin-project provided a master ci.sh script to run exactly the same checks done by CI. This would make it easier to test out local changes to pin-project before submitting a PR.

Weirdly different approach to `Unpin` vs `Drop`

Looking at these two examples

use std::fmt::Debug;
use pin_project::pin_project;
use std::pin::Pin;

pin_project! {
    #[pin_projectable]
    pub struct Foo<T: Debug, U: Debug> {
        #[pin] pinned_field: T,
        unpin_field: U
    }

    #[pinned_drop]
    fn my_drop_fn<T: Debug, U: Debug>(foo: Pin<&mut Foo<T, U>>) {
        let foo = foo.project();
        println!("Dropping pinned field: {:?}", foo.pinned_field);
        println!("Dropping unpin field: {:?}", foo.unpin_field);
    }
}

fn main() {
    Foo { pinned_field: true, unpin_field: 40 };
}
use pin_project::{pin_projectable, UnsafeUnpin};
use std::pin::Pin;

#[pin_projectable(unsafe_Unpin)]
struct Foo<T, U> {
    #[pin]
    future: T,
    field: U,
}

impl<T, U> Foo<T, U> {
    fn baz(self: Pin<&mut Self>) {
        let this = self.project();
        let _: Pin<&mut T> = this.future; // Pinned reference to the field
        let _: &mut U = this.field; // Normal reference to the field
    }
}

unsafe impl<T: Unpin, U> UnsafeUnpin for Foo<T, U> {} // Conditional Unpin impl

it is odd that for a very similar situation (let the user "hook" into the auto-generated trait impl), this crate uses two totally different approaches: one time it is an attribute at the type, and one time it is a block around the entire thing plus an attribute at the impl.

To make the crate easier to use, it would be much better if the same approach could be used both times.

`__UnpinStruct` is restricting the pinned field.

Unless I misunderstand something, it seems the logic to put the field in __UnpinStruct is reversed, as it checks that the #[pin]'ed field are Unpin.

For example:

// This structure cannot be moved
struct Property {
    pin: std::marker::PhantomPinned
}

#[pin_project::pin_project]
struct Container {
    #[pin]
    xxx : Property
}

Result in this error:

error[E0277]: the trait bound `std::marker::PhantomPinned: std::marker::Unpin` is not satisfied in `__unpin_scope_Container::__UnpinStructContainer`
   |
20 | #[pin_project::pin_project]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `__unpin_scope_Container::__UnpinStructContainer`, the trait `std::marker::Unpin` is not implemented for `std::marker::PhantomPinned`
   |

__UnpinStruct constraints all the pin'ed types. But I believe it should be the opposite, only the types that are not pinned should satisfy Unpin.

Provide way to refer to projected type

A couple of things I've wanted to do is to be able to destructure the projection to avoid using this. all the time in methods, and implement helper methods directly on the projection. As an example this currently works because of a lack of hygiene:

#[pin_project::pin_project]
struct Foo {
    #[pin]
    bar: &'static str,
}

impl __FooProjection<'_> {
    fn debug(&self) {
        println!("{:?}", self.bar);
    }
}

fn main() {
    let mut foo = Box::pin(Foo { bar: "baz" });
    foo.as_mut().project().debug();
    let __FooProjection { bar } = foo.as_mut().project();
    println!("{}", bar);
}

but it would be nice to have a way to do this that doesn't rely on the internal details of the macro.

pin-project 0.3.3 introduces breaking changes about "missing extern crate core" compared to 0.3.2

0.3.2

$ cargo update -p pin-project --precise 0.3.2
    Updating crates.io index
    Updating pin-project v0.3.3 -> v0.3.2

$ cargo test
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running target/debug/deps/futures_compat-27fb39e639db3ee7

running 1 test
test implements_error ... ok

0.3.3

$ cargo update -p pin-project --precise 0.3.3
    Updating crates.io index
    Updating pin-project v0.3.2 -> v0.3.3

$ cargo test
   Compiling snafu v0.4.1 (/Users/shep/Projects/snafu)
error[E0433]: failed to resolve: maybe a missing `extern crate core;`?
   --> /Users/shep/Projects/snafu/src/futures/try_future.rs:127:18
    |
127 | #[unsafe_project(Unpin)]
    |                  ^^^^^ maybe a missing `extern crate core;`?

error[E0433]: failed to resolve: maybe a missing `extern crate core;`?
   --> /Users/shep/Projects/snafu/src/futures/try_future.rs:166:18
    |
166 | #[unsafe_project(Unpin)]
    |                  ^^^^^ maybe a missing `extern crate core;`?

error[E0433]: failed to resolve: maybe a missing `extern crate core;`?
   --> /Users/shep/Projects/snafu/src/futures/try_stream.rs:129:18
    |
129 | #[unsafe_project(Unpin)]
    |                  ^^^^^ maybe a missing `extern crate core;`?

error[E0433]: failed to resolve: maybe a missing `extern crate core;`?
   --> /Users/shep/Projects/snafu/src/futures/try_stream.rs:171:18
    |
171 | #[unsafe_project(Unpin)]
    |                  ^^^^^ maybe a missing `extern crate core;`?

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0433`.
error: Could not compile `snafu`.

Implement `replace()` method to move out of struct/enum

Replacing a pinned value is safe as long as the destructors of types which do not implement Unpin are called.

Pin::set allows replacing the whole value, but it does not allow recovering the un-pinned fields, so the idea is to provide a method to achieve this.

The API would look something like:

#[pin_project]
enum Example {
    A(#[pin] PinnedValue),
    B(UnpinnedValue),
    C,
}

...

#[project]
match self.replace_and_project(Example::C) {
    Example::A() => { /* no data */ },
    Example::B(value) => { /* oh look a value! */ },
    Example::C => {},
}

#[project] on non-statement expression does not work without unstable features

playground

Code:

#[project]
fn foo() {
    #[pin_project]
    enum Enum<A> {
        Variant(#[pin] A),
    }

    let mut x = Enum::Variant(1);
    let mut x = Pin::new(&mut x).project();

    Some(
        #[project]
        match x {
            Enum::Variant(x) => {}
        },
    );
}

Error:

error[E0658]: attributes on expressions are experimental
   --> tests/project.rs:230:9
    |
230 |         #[project]
    |         ^^^^^^^^^^
    |
    = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
    = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable

error[E0658]: custom attributes cannot be applied to expressions
   --> tests/project.rs:230:9
    |
230 |         #[project]
    |         ^^^^^^^^^^
    |
    = note: see issue #54727 <https://github.com/rust-lang/rust/issues/54727> for more information
    = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable

Same as taiki-e/auto_enums#90

Rust-Analyzer compatibility

Currently, pin-project's macros aren't expanded by Rust-Analyzer, which prevents things like auto-completing into projections. This is due to pin-project using a bunch of features that Rust-Analyzer still doesn't understand. However, it doesn't look like any of these are ultimately fundamental to the way pin-project works.

  • Attribute proc macros aren't expanded (rust-lang/rust-analyzer#6029)
    • pin-project is already implemented as a derive macro internally, so it'd just require shifting the public API towards it (the existing #[pin_project] can be kept as a compatibility wrapper, so no breakage is required here)
  • Rust-Analyzer doesn't see "macro-private" types (that is, constructs like const _: () = { struct __FooProjection {} };)
    • Workaround: Named projections (#[pin(project = FooProj)]) are already placed in the regular outer scope
  • Rust-Analyzer doesn't see "macro-private" impls (const _: () = { impl Foo {} };
    • Put the fn project() impl in the regular outer scope if the projection type is renamed (and the same for fn project_ref())
  • Rust-Analyzer doesn't infer projection type parameters (let foo: Foo<T>; foo.project() is inferred as FooProj<{unknown}>, rust-lang/rust-analyzer#8100)
    • Workaround: The type is inferred correctly when called using UFCS (let foo: Foo<T>; Foo::project(foo) is inferred correctly as FooProj<T>)
    • This also happens when the impl is written manually, so this seems to be some RA bug that we can't do much about
  • Reexported macro can't be seen properly if also importing #[pin_project]
    • Workaround: Standardize on either #[pin_project] or #[derive(PinProject)] within a single module

Tracking issue for pin-project 0.4

Current prerelease: 0.4.0-beta.1

The most important fix of this release is that pin projection has become a safe operation (#18, thanks @Aaron1011)

Changes

  • #[unsafe_project] has been replaced with #[pin_project]. (#18, #33)
  • The Unpin argument has been removed - an Unpin impl is now generated by default. (#18)
  • Drop impls must be specified with #[pinned_drop] attribute instead of via a normal Drop impl. (#18, #33, #86)
  • Unpin impls must be specified with an impl of UnsafeUnpin, instead of implementing the normal Unpin trait. (#18)
  • Changed project method generated by #[pin_project] attribute to take an &mut Pin<&mut Self> argument. (#47) EDIT: reverted in #90
  • Removed "project_attr" feature and always enable #[project] attribute (#94)
  • #[project] attribute can now be used for impl blocks. (#46)
  • #[project] attribute can now be used for use statements. (#85)
  • Made #[project] attribute disabled by default. (#36, #41) EDIT: replaced with #94
  • Added project_ref method and #[project_ref] attribute. (#93)
  • #[pin_project] attribute now determines the visibility of the projection type/method is based on the original type. (#96)

TODO

Some adjustments are needed.

  • Make error message more obvious (#18 (comment)); done in #22
  • unsafe_Unpin vs UnsafeUnpin vs unsafe_unpin (#18 (comment)); done in #40 (Adopted UnsafeUnpin).
  • Update proc-macro2, syn, and quote to 1.0; done in #23
  • Test code examples in README (#19) EDIT: see #19 (comment)
  • Mention #32 in the documents; done in #34
  • pin-project does not interoperate well with #[cfg()] (#68)

Unresolved issues

  • Different approach to Unpin vs Drop (#26); done in #86
  • Change the argument type of project method back to self: Pin<&mut Self> (#89)

Blockers

I plan to have a few alpha releases before the blockers are resolved.

Generated `#[deny(safe_packed_borrows)]` is not compatible with `#![forbid(future_incompatible)]`

The compiler's built-in #[deny(future_incompatible)] seems to be incompatible with pin-project-internal. It seems #[deny(safe_packed_borrows)] will be disallowed in the future, but pin-project generates code that uses that lint under certain circumstances. Given the Rust 2021 edition may turn all 2018 warnings into errors, this may become a problem.

I'm not exactly sure what triggers this, but adding the lint to the current main of tide surfaces the error. Though I feel I've seen this happen before when working on other crates. I'm not sure what the right outcome here is, but thought it might be important enough to raise. Thanks!

#34 seems related.

Screenshot

Screenshot 2020-09-26 19 20 16

?Sized type parameters don't work

?Sized type parameters don't work unless they are also the last type parameter.

use pin_project::pin_project;

#[pin_project]
pub struct Foo<'a, I: ?Sized, Item>
where
    I: Iterator,
{
    iter: &'a mut I,
    item: Option<Item>,
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `I` cannot be known at compilation time
 --> src/lib.rs:3:1
  |
3 | #[pin_project]
  | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
4 | pub struct Foo<'a, I: ?Sized, Item>
  |                    - this type parameter needs to be `std::marker::Sized`
  |
  = help: the trait `std::marker::Sized` is not implemented for `I`
  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
  = note: only the last element of a tuple may have a dynamically sized type
  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Odd unused warning on non pinned item

I'm getting an odd dead_code warning when im obviously using key in the Ready(Ok(svc)) branch. I think this has to do with the pin-project macro.

#[pin_project]
#[derive(Debug)]
struct UnreadyService<K, S, Req> {
    // This is a false positive
	// this is warning that it is unused
    key: Option<K>,
    #[pin]
    cancel: oneshot::Receiver<()>,
    #[pin]
    ready: Ready<S, Req>,
}

impl<K, S: Service<Req>, Req> Future for UnreadyService<K, S, Req> {
    type Output = Result<(K, S), (K, Error<S::Error>)>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let me = self.project();

        if let Poll::Ready(Ok(())) = me.cancel.poll(cx) {
            let key = self.key.take().expect("polled after ready");
            return Poll::Ready(Err((key, Error::Canceled)));
        }

        match me.ready.poll(cx) {
            Poll::Pending => Poll::Pending,
            Poll::Ready(Ok(svc)) => {
				// but it is used here
                let key = self.key.take().expect("polled after ready");
                Ok((key, svc)).into()
            }
            Poll::Ready(Err(e)) => {
                let key = self.key.take().expect("polled after ready");
                Err((key, Error::Inner(e))).into()
            }
        }
    }
}

#![feature(overlapping_marker_traits)] breaks the guarantee for Unpin provided by pin-project

UPDATE2(2020/01/27):

This will be fixed in rust-lang/rust#68544


UPDATE(2019/09/26):

overlapping_marker_traits is replaced with marker_trait_attr.
marker_trait_attr doesn't seem to break the guarantee (added test in #110). So, once overlapping_marker_traits is removed, close this issue.


pin-project provides an appropriate Unpin implementation by default. Since overlapping implementations are prohibited, this ensures that users cannot add inappropriate Unpin implementations.

However, currently, this guarantee can be broken by enabling #[feature(overlapping_marker_traits)]: playground

@cramertj has already pointed out this in rust-lang/rust#29864 (comment).
And it seems that it is planned to make #[feature(overlapping_marker_traits)] available only with explicitly allowed traits, but it doesn't seem to be fully implemented yet.


Thanks to @RalfJung for pointing out the interaction with this feature.

PinnedDrop implementations can contain unsafe code without an unsafe block

Since the #[pinned_drop] attribute injects an unsafe onto the drop fn, code within the drop implementation can perform unsafe operations without an explicit unsafe block.

You could potentially instead generate something like

impl PinnedDrop for Foo {
    unsafe fn drop(self: Pin<&mut Self>) {
        fn drop_inner(self: Pin<&mut Self>) {
            // user code here
        }
        drop_inner(self);
    }
}

Consider merging this crate and pin-utils

The pin-utils crate provides three macros: pin_mut, unsafe_pinned, and unsafe_unpinned.

The #[pin_project] attribute provided by this crate is strictly more powerful than unsafe_pinned and unsafe_unpinned - it ensures safety by default, but lets you opt-out via unsafe to get the unchecked behavior of unsafe_pinned and unsafe_unpinned.

The only thing this crate is missing is the pin_mut macro, which is a small macro_rules! macro.

I think it would be useful for there to be a single crate which handles all of these pinning operations. Currently, users that want both safe pin projections and stack pinning need to use two separate crates.

pin-project does not interoperate well with #[cfg()]

Take this struct for instance:

#[pin_project]
#[derive(Debug)]
pub struct Socket {
    #[cfg_attr(unix, pin)]
    #[cfg(unix)]
    inner: tokio::net::unix::UnixStream,
    #[cfg_attr(windows, pin)]
    #[cfg(windows)]
    inner: tokio_named_pipes::NamedPipe,
}

I get the error

error[E0124]: field `inner` is already declared
  --> src/io/socket.rs:29:5
   |
26 |     inner: tokio::net::unix::UnixStream,
   |     ----------------------------------- `inner` first declared here
...
29 |     inner: tokio_named_pipes::NamedPipe,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field already declared

Even though, as far as I can tell, this should work. My guess here is that pin-project is run before the #[cfg()]s are evaluated, and ends up not propagating them, but I'm not sure?

Regression: cannot return value referencing function parameter `self`

Caused by #47.

Such code is used a lot in futures etc., so I would like to support it...
However, I'm not sure if this can be fixed by ways other than changing self argument to self: Pin<&mut Self>.

Code:

use std::pin::Pin;

#[pin_project::pin_project]
struct Struct<T, U> {
    #[pin]
    pinned: T,
    unpinned: U,
}

impl<T, U> Struct<T, U> {
    fn get_pin_mut<'a>(mut self: Pin<&'a mut Self>) -> Pin<&'a mut T> {
        self.project().pinned
    }
}

Error:

error[E0515]: cannot return value referencing function parameter `self`
  --> src/lib.rs:33:9
   |
33 |         self.project().pinned
   |         ----^^^^^^^^^^^^^^^^^
   |         |
   |         returns a value referencing data owned by the current function
   |         `self` is borrowed here

playground (current)

playground (previous)

Related: rust-lang/rust#54934

"unused result" warning with 0.4.18

I just updated from 0.4.17 to 0.4.18 and I now receive the following warning:

#![warn(unused_results)]

use pin_project::pin_project;

#[pin_project]
pub struct Wrapper<T> {
    #[pin]
    t: T,
}
warning: unused result
  --> src/lib.rs:83:3
   |
83 |           #[pin]
   |  _________^
84 | |         t: T,
   | |____________^

warning: unused result
  --> src/lib.rs:83:3
   |
83 |           #[pin]
   |  _________^
84 | |         t: T,
   | |____________^

rustc: nightly-2020-06-04

Cannot build with RUSTFLAGS="-Zsanitizer=address"

cargo build finishes ok

   Compiling pin-project v1.0.7 (/rust/registry/src/github.com-1ecc6299db9ec823/pin-project-1.0.7)
    Finished dev [unoptimized + debuginfo] target(s) in 11.24s

But RUSTFLAGS="-Zsanitizer=address" cargo build errors with

Compiling pin-project-internal v1.0.7
   Compiling pin-project v1.0.7 (/rust/registry/src/github.com-1ecc6299db9ec823/pin-project-1.0.7)
error: /rust/registry/src/github.com-1ecc6299db9ec823/pin-project-1.0.7/target/debug/deps/libpin_project_internal-93b7f2afde7461c5.so: undefined symbol: __asan_stack_free_7
  --> src/lib.rs:82:9
   |
82 | pub use pin_project_internal::pin_project;
   |         ^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: could not compile `pin-project`

Warnings without line numbers

This is like a rustc bug, but I never saw this before using this crate, so I thought I'd report it here, since you know the ins of pin_project better. I haven't reported on rust repo for now.

#[ project ]
//
fn poll_ready( mut self: Pin<&mut Self>, cx: &mut Context<'_> ) -> Poll<Result<(), Self::Error>>
{
	#[ project ]
	//
	match self.project()
	{
		Sender::Bounded  { tx, .. } => tx.poll_ready( cx ).map_err( Into::into ),
		Sender::Unbounded{ tx, .. } => tx.poll_ready( cx ).map_err( Into::into ),
	}
}

Note the unnecessary mut before self. The warning is:

   Compiling pharos v0.2.2 (/pharos)
warning: variable does not need to be mutable
  |
  = note: `#[warn(unused_mut)]` on by default

No file, no line number, pretty obscure.

pin_project!() fails for type with ?Sized bound

I did see #112, but this is maybe a related problem?

pin_project! {
    /// A unified `Stream` and `Sink` interface to an underlying I/O object, using
    /// the `Encoder` and `Decoder` traits to encode and decode frames.
    ///
    /// You can create a `Framed` instance by using the `AsyncRead::framed` adapter.
    pub struct Framed<T, U, I> where I: ?Sized {
        #[pin]
        inner: FramedRead2<FramedWrite2<Fuse<T, U>>>,
        _item: PhantomData<I>,
    }
}

results in

error: no rules expected the token `?`
  --> tokio-util/src/codec/framed_write.rs:20:46
   |
20 |     pub struct FramedWrite<T, E, I> where I: ?Sized {
   |                                              ^ no rules expected this token in macro call

Not possible to call project when struct contains associated type

#[pin_project]
pub struct ServiceList<T> where T: IntoIterator,
{
    inner: T::IntoIter,
}

No impl Unpin is generated for this struct, so if I later write:

fn poll(
    mut self: Pin<&mut Self>,
    _: &mut Context<'_>,
) -> Poll<...> {
    match self.project().inner.next() {

it fails to compile with

error[E0596]: cannot borrow data in a dereference of `std::pin::Pin<&mut <T as std::iter::IntoIterator>::IntoIter>` as mutable
  --> tower-discover/src/list.rs:49:15
   |
49 |         match self.project().inner.next() {
   |               ^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `std::pin::Pin<&mut <T as std::iter::IntoIterator>::IntoIter>`

Cannot compile with ?Sized struct

Code:

#[pin_project]
pub struct A<T: ?Sized> {
    x: T,
}

Error:

the size for values of type `T` cannot be known at compilation time

doesn't have a size known at compile-time

help: within `dst::A<T>`, the trait `core::marker::Sized` is not implemented for `T`
note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
help: consider adding a `where T: core::marker::Sized` bound
note: required because it appears within the type `dst::A<T>`
note: all local variables must have a statically known size
help: unsized locals are gated as an unstable feature

pin_project cannot be used with structs that hold mutable references

Hello,

I just tried using pin-project, as it looks like a really nice helper!

However, while doing so, I hit a wall: with pin-project = "0.4.17",

#[pin_project::pin_project]
pub struct Foo<'a, R> {
    buf: &'a mut [u8],

    #[pin]
    stuff: R,
}

impl<'a, R> Foo<'a, R> {
    fn foo(self: std::pin::Pin<&mut Self>) {
        let this = self.project();
        *this.buf = &mut this.buf[1..];
    }
}

fn main() {
}

fails to compile with this error message:

   Compiling foo v0.1.0 (/tmp/foo)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'pin in function call due to conflicting requirements
  --> src/main.rs:11:25
   |
11 |         let this = self.project();
   |                         ^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 10:5...
  --> src/main.rs:10:5
   |
10 | /     fn foo(self: std::pin::Pin<&mut Self>) {
11 | |         let this = self.project();
12 | |         *this.buf = &mut this.buf[1..];
13 | |     }
   | |_____^
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the impl at 9:6...
  --> src/main.rs:9:6
   |
9  | impl<'a, R> Foo<'a, R> {
   |      ^^
note: ...so that the types are compatible
  --> src/main.rs:11:25
   |
11 |         let this = self.project();
   |                         ^^^^^^^
   = note: expected  `std::pin::Pin<&mut Foo<'_, R>>`
              found  `std::pin::Pin<&mut Foo<'a, R>>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
error: could not compile `foo`.

Weirdly enough, replacing &'a mut by &'a works, so I'd guess something has been implemented specifically for &'a but hasn't been implemented for &'a mut?

Do you think it'd be possible to handle this in pin-project, or is it something that can't be fixed and I should just not use it? :)

Lifetime issue when `#[pin_project]` is used

Playground link

This code:

use pin_project::pin_project;

trait Bar<X> {
    type Y;
}

struct Example<A>(A);

impl<X, T> Bar<X> for Example<T> {
    type Y = Option<T>;
}

#[pin_project]
struct Foo<A, B> {
    x: <Example<A> as Bar<B>>::Y
}

Fails to compile with the error:

error[E0309]: the parameter type `A` may not live long enough
  --> src/main.rs:13:1
   |
13 | #[pin_project]
   | ^^^^^^^^^^^^^^
14 | struct Foo<A, B> {
   |            - help: consider adding an explicit lifetime bound...: `A: 'pin`
   |
note: ...so that the reference type `&'pin mut std::option::Option<A>` does not outlive the data it points at
  --> src/main.rs:13:1
   |
13 | #[pin_project]
   | ^^^^^^^^^^^^^^
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

It's possibly a compiler bug, because if I change Option<A> to A it compiles fine, which is really weird...

This is the expanded code produced by pin-project:

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
use pin_project::pin_project;
trait Bar<X> {
    type Y;
}
struct Example<A>(A);
impl<X, T> Bar<X> for Example<T> {
    type Y = Option<T>;
}
struct Foo<A, B> {
    x: <Example<A> as Bar<B>>::Y,
}
#[allow(clippy::mut_mut)]
#[allow(dead_code)]
struct __FooProjection<'pin, A, B> {
    x: &'pin mut (<Example<A> as Bar<B>>::Y),
}
#[allow(dead_code)]
struct __FooProjectionRef<'pin, A, B> {
    x: &'pin (<Example<A> as Bar<B>>::Y),
}
impl<A, B> Foo<A, B> {
    fn project<'pin>(self: ::core::pin::Pin<&'pin mut Self>) -> __FooProjection<'pin, A, B> {
        unsafe {
            let Foo { x } = self.get_unchecked_mut();
            __FooProjection { x }
        }
    }
    fn project_ref<'pin>(self: ::core::pin::Pin<&'pin Self>) -> __FooProjectionRef<'pin, A, B> {
        unsafe {
            let Foo { x } = self.get_ref();
            __FooProjectionRef { x }
        }
    }
}
#[allow(single_use_lifetimes)]
#[allow(non_snake_case)]
#[deny(safe_packed_borrows)]
fn __pin_project_assert_not_repr_packed_Foo<A, B>(val: &Foo<A, B>) {
    &val.x;
}
#[allow(non_snake_case)]
fn __unpin_scope_Foo() {
    struct __Foo<'pin, A, B> {
        __pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (A, B)>,
    }
    impl<'pin, A, B> ::core::marker::Unpin for Foo<A, B> where __Foo<'pin, A, B>: ::core::marker::Unpin {}
}
trait FooMustNotImplDrop {}
#[allow(clippy::drop_bounds)]
impl<T: ::core::ops::Drop> FooMustNotImplDrop for T {}
#[allow(single_use_lifetimes)]
impl<A, B> FooMustNotImplDrop for Foo<A, B> {}
#[allow(single_use_lifetimes)]
impl<A, B> ::pin_project::__private::PinnedDrop for Foo<A, B> {
    unsafe fn drop(self: ::core::pin::Pin<&mut Self>) {}
}

Tracking issue for 1.0.0 release

Current pre-release: 1.0.0-alpha.1

There haven't been any API changes since the #[project] attribute was deprecated. Since there are currently no open issues, I think it's a good time to release version 1.0.0.

Since this is a Semver-incompatible release, we could take the opportunity to remove the #[project], #[project_ref], and #[project_replace] attributes. Otherwise, I don't think any changes need to be made other than bumping the version number.

Visibility of projected type

Currently, visibility of the projected type and projection trait are always pub(self), but we may use the original type visibility (but pub is downgraded to pub(crate))

Deprecate #[project] attributes in favor of the naming of projected-type

The naming of projected-type added in #202 is more powerful than project* attributes and the implementation is also very simple.

There some reasons for removing project* attributes in favor of the naming of projected-type:

  • project* attributes aren't really available everywhere, and there are some unsupported cases (e.g., #124 (comment)).
  • Each projection method requires a separate project* attribute.
  • Having multiple ways to do the same is a bit confusing.
  • We can avoid some problems (the implementation complexity and poor testing due to it) made that caused regressions like #206/hyperium/hyper#2199.
  • Compatible with pin-project-lite. pin-project-lite may be able to support naming in the future (especially required if it supports enums).

That said, it may be tedious to name each time...

Can bypass `repr(packed)` checking by hiding it in a proc-macro-attribute

Given a proc-macro crate like this:

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro_attribute]
pub fn hidden_repr(attr: TokenStream, item: TokenStream) -> TokenStream {
    format!("#[repr({})] {}", attr, item).parse().unwrap()
}

Using it along with pin-project in a project can cause a value to be pinned in one location and dropped in another:

use core::pin::Pin;
use hidden_repr::hidden_repr;
use pin_project::pin_projectable;

#[derive(Debug)]
struct Foo(u16);

impl Foo {
    fn foo(self: Pin<&mut Self>) {
        println!("{:?} at {:p}", self, self);
    }
}

impl Drop for Foo {
    fn drop(&mut self) {
        println!("{:?} dropped at {:p}", self, self);
    }
}

#[pin_projectable]
#[hidden_repr(packed)]
struct Bar {
    _bar: u8,
    #[pin]
    foo: Foo,
}

fn main() {
    let mut bar = Box::pin(Bar { _bar: 0, foo: Foo(0) });
    bar.as_mut().project().foo.foo();
}

output:

Foo(0) at 0x560220317a41
Foo(0) dropped at 0x7fff2b8510b6

(it appears proc-macro-attribute application order is not defined, so not guaranteed to reproduce, but this seems like the sane order for rustc to apply them in so it's likely to continue working).

pin-project 0.4.11 breaks hyper

Hello, hyper uses #[project] on an expression https://github.com/hyperium/hyper/blob/v0.13.5/src/server/conn.rs#L926 and https://github.com/hyperium/hyper/blob/v0.13.5/src/server/shutdown.rs#L65 which now causes a compilation error with pin-project 0.4.11.

Here is one of your test cases adapted to demonstrate the issue, this code works fine with 0.4.10 but not 0.4.11:

#[project]
fn foo() {
    #[pin_project]
    enum Enum<A> {
        Variant(#[pin] A),
    }

    let mut x = Enum::Variant(1);
    let mut x = Pin::new(&mut x).project();

    let asdf = {
        #[project]
        match x {
            Enum::Variant(x) => {}
        }
    };

    Some(asdf);
}

Error:

error[E0658]: attributes on expressions are experimental
  --> src/main.rs:16:9
   |
16 |         #[project]
   |         ^^^^^^^^^^
   |
   = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
   = help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable

error: cannot find attribute `derive` in this scope

Since nightly-2021-02-08, our test suite failed to compile.

related: rust-lang/rust#79078, rust-lang/rust#79202

rustc: rustc 1.52.0-nightly (9778068cb 2021-02-07)

https://github.com/taiki-e/pin-project/runs/1851328341?check_suite_focus=true

log
error: cannot find attribute `derive` in this scope
 --> tests/no-core/../include/basic-safe-part.rs:4:3
  |
4 | #[derive(Debug)]
  |   ^^^^^^

error: cannot find attribute `derive` in this scope
 --> tests/no-core/../include/basic-safe-part.rs:3:1
  |
3 | #[::pin_project::pin_project]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
 --> tests/no-core/../include/basic-safe-part.rs:6:7
  |
6 |     #[pin]
  |       ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:15:3
   |
15 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:11:1
   |
11 | / #[::pin_project::pin_project(
12 | |     project = DefaultStructNamedProj,
13 | |     project_ref = DefaultStructNamedProjRef,
14 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:17:7
   |
17 |     #[pin]
   |       ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:23:3
   |
23 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:22:1
   |
22 | #[::pin_project::pin_project]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:24:39
   |
24 | pub struct DefaultTupleStruct<T, U>(#[pin] pub T, pub U);
   |                                       ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:30:3
   |
30 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:26:1
   |
26 | / #[::pin_project::pin_project(
27 | |     project = DefaultTupleStructNamedProj,
28 | |     project_ref = DefaultTupleStructNamedProjRef,
29 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:31:44
   |
31 | pub struct DefaultTupleStructNamed<T, U>(#[pin] pub T, pub U);
   |                                            ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:37:3
   |
37 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:33:1
   |
33 | / #[::pin_project::pin_project(
34 | |     project = DefaultEnumProj,
35 | |     project_ref = DefaultEnumProjRef,
36 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:40:11
   |
40 |         #[pin]
   |           ^^^

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:44:13
   |
44 |     Tuple(#[pin] T, U),
   |             ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:49:3
   |
49 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:48:1
   |
48 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:51:7
   |
51 |     #[pin]
   |       ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:62:3
   |
62 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:61:1
   |
61 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:63:42
   |
63 | pub struct PinnedDropTupleStruct<T, U>(#[pin] pub T, pub U);
   |                                          ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:75:3
   |
75 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:70:1
   |
70 | / #[::pin_project::pin_project(
71 | |     PinnedDrop,
72 | |     project = PinnedDropEnumProj,
73 | |     project_ref = PinnedDropEnumProjRef,
74 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:78:11
   |
78 |         #[pin]
   |           ^^^

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:82:13
   |
82 |     Tuple(#[pin] T, U),
   |             ^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:92:3
   |
92 | #[derive(Debug)]
   |   ^^^^^^

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:91:1
   |
91 | #[::pin_project::pin_project(project_replace)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:94:7
   |
94 |     #[pin]
   |       ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:104:3
    |
104 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:99:1
    |
99  | / #[::pin_project::pin_project(
100 | |     project = ReplaceStructNamedProj,
101 | |     project_ref = ReplaceStructNamedProjRef,
102 | |     project_replace = ReplaceStructNamedProjOwn,
103 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:106:7
    |
106 |     #[pin]
    |       ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:112:3
    |
112 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:111:1
    |
111 | #[::pin_project::pin_project(project_replace)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:113:39
    |
113 | pub struct ReplaceTupleStruct<T, U>(#[pin] pub T, pub U);
    |                                       ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:120:3
    |
120 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:115:1
    |
115 | / #[::pin_project::pin_project(
116 | |     project = ReplaceTupleStructNamedProj,
117 | |     project_ref = ReplaceTupleStructNamedProjRef,
118 | |     project_replace = ReplaceTupleStructNamedProjOwn,
119 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:121:44
    |
121 | pub struct ReplaceTupleStructNamed<T, U>(#[pin] pub T, pub U);
    |                                            ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:128:3
    |
128 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:123:1
    |
123 | / #[::pin_project::pin_project(
124 | |     project = ReplaceEnumProj,
125 | |     project_ref = ReplaceEnumProjRef,
126 | |     project_replace = ReplaceEnumProjOwn,
127 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:131:11
    |
131 |         #[pin]
    |           ^^^

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:135:13
    |
135 |     Tuple(#[pin] T, U),
    |             ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:140:3
    |
140 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:139:1
    |
139 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:142:7
    |
142 |     #[pin]
    |       ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:148:3
    |
148 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:147:1
    |
147 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:149:43
    |
149 | pub struct UnsafeUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
    |                                           ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:156:3
    |
156 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:151:1
    |
151 | / #[::pin_project::pin_project(
152 | |     UnsafeUnpin,
153 | |     project = UnsafeUnpinEnumProj,
154 | |     project_ref = UnsafeUnpinEnumProjRef,
155 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:159:11
    |
159 |         #[pin]
    |           ^^^

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:163:13
    |
163 |     Tuple(#[pin] T, U),
    |             ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:168:3
    |
168 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:167:1
    |
167 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:170:7
    |
170 |     #[pin]
    |       ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:176:3
    |
176 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:175:1
    |
175 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:177:40
    |
177 | pub struct NotUnpinTupleStruct<T, U>(#[pin] pub T, pub U);
    |                                        ^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:184:3
    |
184 | #[derive(Debug)]
    |   ^^^^^^

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:179:1
    |
179 | / #[::pin_project::pin_project(
180 | |     !Unpin,
181 | |     project = NotUnpinEnumProj,
182 | |     project_ref = NotUnpinEnumProjRef,
183 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:187:11
    |
187 |         #[pin]
    |           ^^^

error: cannot find attribute `pin` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:191:13
    |
191 |     Tuple(#[pin] T, U),
    |             ^^^

error: cannot find attribute `derive` in this scope
 --> tests/no-core/../include/basic-safe-part.rs:3:1
  |
3 | #[::pin_project::pin_project]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:11:1
   |
11 | / #[::pin_project::pin_project(
12 | |     project = DefaultStructNamedProj,
13 | |     project_ref = DefaultStructNamedProjRef,
14 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:22:1
   |
22 | #[::pin_project::pin_project]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:26:1
   |
26 | / #[::pin_project::pin_project(
27 | |     project = DefaultTupleStructNamedProj,
28 | |     project_ref = DefaultTupleStructNamedProjRef,
29 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:33:1
   |
33 | / #[::pin_project::pin_project(
34 | |     project = DefaultEnumProj,
35 | |     project_ref = DefaultEnumProjRef,
36 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:48:1
   |
48 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:61:1
   |
61 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:70:1
   |
70 | / #[::pin_project::pin_project(
71 | |     PinnedDrop,
72 | |     project = PinnedDropEnumProj,
73 | |     project_ref = PinnedDropEnumProjRef,
74 | | )]
   | |__^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
  --> tests/no-core/../include/basic-safe-part.rs:91:1
   |
91 | #[::pin_project::pin_project(project_replace)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:99:1
    |
99  | / #[::pin_project::pin_project(
100 | |     project = ReplaceStructNamedProj,
101 | |     project_ref = ReplaceStructNamedProjRef,
102 | |     project_replace = ReplaceStructNamedProjOwn,
103 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:111:1
    |
111 | #[::pin_project::pin_project(project_replace)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:115:1
    |
115 | / #[::pin_project::pin_project(
116 | |     project = ReplaceTupleStructNamedProj,
117 | |     project_ref = ReplaceTupleStructNamedProjRef,
118 | |     project_replace = ReplaceTupleStructNamedProjOwn,
119 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:123:1
    |
123 | / #[::pin_project::pin_project(
124 | |     project = ReplaceEnumProj,
125 | |     project_ref = ReplaceEnumProjRef,
126 | |     project_replace = ReplaceEnumProjOwn,
127 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:139:1
    |
139 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:147:1
    |
147 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:151:1
    |
151 | / #[::pin_project::pin_project(
152 | |     UnsafeUnpin,
153 | |     project = UnsafeUnpinEnumProj,
154 | |     project_ref = UnsafeUnpinEnumProjRef,
155 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:167:1
    |
167 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:175:1
    |
175 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: cannot find attribute `derive` in this scope
   --> tests/no-core/../include/basic-safe-part.rs:179:1
    |
179 | / #[::pin_project::pin_project(
180 | |     !Unpin,
181 | |     project = NotUnpinEnumProj,
182 | |     project_ref = NotUnpinEnumProjRef,
183 | | )]
    | |__^
    |
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
 --> tests/no-core/../include/basic-safe-part.rs:3:1
  |
3 | #[::pin_project::pin_project]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
  |
  = note: `-D legacy-derive-helpers` implied by `-D warnings`
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:11:1
   |
11 | / #[::pin_project::pin_project(
12 | |     project = DefaultStructNamedProj,
13 | |     project_ref = DefaultStructNamedProjRef,
14 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:22:1
   |
22 | #[::pin_project::pin_project]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:26:1
   |
26 | / #[::pin_project::pin_project(
27 | |     project = DefaultTupleStructNamedProj,
28 | |     project_ref = DefaultTupleStructNamedProjRef,
29 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:33:1
   |
33 | / #[::pin_project::pin_project(
34 | |     project = DefaultEnumProj,
35 | |     project_ref = DefaultEnumProjRef,
36 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:48:1
   |
48 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:61:1
   |
61 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:70:1
   |
70 | / #[::pin_project::pin_project(
71 | |     PinnedDrop,
72 | |     project = PinnedDropEnumProj,
73 | |     project_ref = PinnedDropEnumProjRef,
74 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:91:1
   |
91 | #[::pin_project::pin_project(project_replace)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:99:1
    |
99  | / #[::pin_project::pin_project(
100 | |     project = ReplaceStructNamedProj,
101 | |     project_ref = ReplaceStructNamedProjRef,
102 | |     project_replace = ReplaceStructNamedProjOwn,
103 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:111:1
    |
111 | #[::pin_project::pin_project(project_replace)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:115:1
    |
115 | / #[::pin_project::pin_project(
116 | |     project = ReplaceTupleStructNamedProj,
117 | |     project_ref = ReplaceTupleStructNamedProjRef,
118 | |     project_replace = ReplaceTupleStructNamedProjOwn,
119 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:123:1
    |
123 | / #[::pin_project::pin_project(
124 | |     project = ReplaceEnumProj,
125 | |     project_ref = ReplaceEnumProjRef,
126 | |     project_replace = ReplaceEnumProjOwn,
127 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:139:1
    |
139 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:147:1
    |
147 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:151:1
    |
151 | / #[::pin_project::pin_project(
152 | |     UnsafeUnpin,
153 | |     project = UnsafeUnpinEnumProj,
154 | |     project_ref = UnsafeUnpinEnumProjRef,
155 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:167:1
    |
167 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:175:1
    |
175 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:179:1
    |
179 | / #[::pin_project::pin_project(
180 | |     !Unpin,
181 | |     project = NotUnpinEnumProj,
182 | |     project_ref = NotUnpinEnumProjRef,
183 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
 --> tests/no-core/../include/basic-safe-part.rs:3:1
  |
3 | #[::pin_project::pin_project]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
  |
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
  = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:11:1
   |
11 | / #[::pin_project::pin_project(
12 | |     project = DefaultStructNamedProj,
13 | |     project_ref = DefaultStructNamedProjRef,
14 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:22:1
   |
22 | #[::pin_project::pin_project]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:26:1
   |
26 | / #[::pin_project::pin_project(
27 | |     project = DefaultTupleStructNamedProj,
28 | |     project_ref = DefaultTupleStructNamedProjRef,
29 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:33:1
   |
33 | / #[::pin_project::pin_project(
34 | |     project = DefaultEnumProj,
35 | |     project_ref = DefaultEnumProjRef,
36 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:48:1
   |
48 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:61:1
   |
61 | #[::pin_project::pin_project(PinnedDrop)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:70:1
   |
70 | / #[::pin_project::pin_project(
71 | |     PinnedDrop,
72 | |     project = PinnedDropEnumProj,
73 | |     project_ref = PinnedDropEnumProjRef,
74 | | )]
   | |__^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
  --> tests/no-core/../include/basic-safe-part.rs:91:1
   |
91 | #[::pin_project::pin_project(project_replace)]
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:99:1
    |
99  | / #[::pin_project::pin_project(
100 | |     project = ReplaceStructNamedProj,
101 | |     project_ref = ReplaceStructNamedProjRef,
102 | |     project_replace = ReplaceStructNamedProjOwn,
103 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:111:1
    |
111 | #[::pin_project::pin_project(project_replace)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:115:1
    |
115 | / #[::pin_project::pin_project(
116 | |     project = ReplaceTupleStructNamedProj,
117 | |     project_ref = ReplaceTupleStructNamedProjRef,
118 | |     project_replace = ReplaceTupleStructNamedProjOwn,
119 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:123:1
    |
123 | / #[::pin_project::pin_project(
124 | |     project = ReplaceEnumProj,
125 | |     project_ref = ReplaceEnumProjRef,
126 | |     project_replace = ReplaceEnumProjOwn,
127 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:139:1
    |
139 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:147:1
    |
147 | #[::pin_project::pin_project(UnsafeUnpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:151:1
    |
151 | / #[::pin_project::pin_project(
152 | |     UnsafeUnpin,
153 | |     project = UnsafeUnpinEnumProj,
154 | |     project_ref = UnsafeUnpinEnumProjRef,
155 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:167:1
    |
167 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:175:1
    |
175 | #[::pin_project::pin_project(!Unpin)]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: derive helper attribute is used before it is introduced
   --> tests/no-core/../include/basic-safe-part.rs:179:1
    |
179 | / #[::pin_project::pin_project(
180 | |     !Unpin,
181 | |     project = NotUnpinEnumProj,
182 | |     project_ref = NotUnpinEnumProjRef,
183 | | )]
    | |__^ the attribute is introduced here
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 119 previous errors

error: could not compile `no-core`

Consider allowing naming the projected type

Currently, all ways for referring the projected type are provided by the #[project] attribute.

Ideally, I would like to write using inherent associated types (rust-lang/rust#8995) or generic associated types (rust-lang/rust#44265) as follows, but neither has been implemented yet:

impl Foo {
    type Projection<'pin> = __FooProjection<'pin>;
}

As implementing these features will take time (it seems that at least Chalk integration is necessary), we may allow naming as an alternative at this time.

I think there are two ways to provide these:

  • #43 (comment)

    Another way is to allow naming the projected-type via the #[pin_project] attribute's argument.

    #[pin_project::pin_project(projection = Bar)]
    struct Foo {
        #[pin]
        bar: &'static str,
    }
    
    impl Bar<'_> {
        fn debug(&self) {}
    }

    We need to document that new lifetimes will be added

  • #85 (comment)

    // TODO: Consider allowing the projected type to be renamed by `#[project] use Foo as Bar`.

Related: #43

Unhelpful Error with #[project] when ommitting dummy attribute on nightly and forgetting mut on self

Apologies for the long title, this issue is hard to put in a sentence. Basically I upgraded from a previous alpha to alpha 7 and ended up with something like this modified example code (from the docs on #[project]):

    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> {
        // no dummy attribute on nightly
        // forgot 'mut' self here
        fn baz(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 => {}
            }
        }
    }

As I am on nightly (tested on latest 2019-09-02 und 2019-08-21), I didn't put the dummy #[project] on the function itself. Then my code didn't have the mut self (I think this wasn't required in a previous version?). With the code in question rustc literally just outputs
error[E0596]: cannot borrow self as mutable, as it is not declared as mutable
without any further information in what file or line the error actually occurs.

Putting the #[project] attribute on the function produces a proper error message:

error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable               
--> libs.rs:148:19
    |                                                                                               
146 |         fn baz(self: Pin<&mut Self>) {                                                     
    |                ---- help: consider changing this to be mutable: `mut self`                       
147 |             #[project]                                                                         
148 |             match self.project() {       
    |                   ^^^^ cannot borrow as mutable    

I don't know enough about proc macros to tell whether anything can be done about this or if its just a rustc issue, so I'm posting it here for now.

Change the argument type of project method back to `self: Pin<&mut Self>`

The signature of the generated project method changes as follows.

before:

fn project(self: &mut Pin<&mut Self>) -> ProjectedType;

after:

fn project(self: Pin<&mut Self>) -> ProjectedType;

The advantage of the current approach is that you can call the project method multiple times without .as_mut().

However, there are drawbacks such as requiring a different method to avoid lifetime issues (#65), and not being able to call the method without importing trait (#21 (comment)).

Also, by reverting this, the code generated by the macro will be simpler.

Related: #47 (comment)

PR: #90

Leaked UB in enums

The docs for #[pin_project] attribute state:

This attribute is completely safe. In the absence of other unsafe code that you write, it is impossible to cause undefined behavior with this attribute.

However, somehow we've managed to accidentally hit it in the following code:

#[pin_project(project = SessionProj)]
#[derive(From)]
pub enum Session<M: meta::Input> {
    Init(#[pin] Init<M>),
    Connected(#[pin] Connected<M>),
    Terminated,
}

impl<M: meta::Input> Stream for Session<M> {
    type Item = String;

    fn poll_next(
        mut self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Self::Item>> {
        let action = match self.as_mut().project() {
            SessionProj::Init(s) => s.poll_next(cx),
            SessionProj::Connected(s) => s.poll_next(cx),
            SessionProj::Terminated => return Poll::Ready(None),
        };

        if let Some(into_phase) = action.transition {
            // This line causes the UB.
            let curr_phase = mem::replace(&mut *self, Self::Terminated);
            let new_phase = match (curr_phase, into_phase) {
                (Self::Init(s), Transition::Connected) => {
                    Self::Connected(s.into())
                }
                (_, Transition::Terminated) => Self::Terminated,
                _ => unreachable!(),
            };
            *self = new_phase;
            // And here, at the end of this block we do receive segfault on `Drop`.
        }

        action.result
    }
}

It seems that we've violated structural Pin guarantees by moving the pinned field, because project_replace doesn't allow us to do the same we're doing with mem::replace here. Also, wrapping the field into Option like this Connected(#[pin] Option<Connected<M>>) helped (as we now moving not the whole Option, but its content only).

Another way we're testing at the moment is removing structural pinning from the enum and doing it more precisely

        let action = match self.as_mut().project() {
            SessionProj::Init(s) => Pin::new(s).poll_next(cx),
            SessionProj::Connected(s) => Pin::new(s).poll_next(cx),
            SessionProj::Terminated => return Poll::Ready(None),
        };

so we're not trying to move pinned fields at all.

But the thing that worries us a lot, that it has been introduced without any portion of unsafe from user code, so we were expecting a compile error if something with Pining is not correct.

I'm still not sure I do understand the issue causes correctly, we still do test different code variants to make sure it's raised by #[pin_project] and not our user code. But if it's really a soundness hole, we should figure out some way to close it.

Const projection from `Pin<&Self>`

In my pet crate, i have to work a lot with Pin<&T> but without the mut (because it uses Cell internally, but nothing to do with futures). And i end up needing to do lots of projections.

Would it make sense for the macro to also have a project_const(self: Pin<&'a Self>) -> FooProjectionConst<'a> ?

(Actually, I feel like it should just be project(), and the current &mut Self should be renamed project_mut for consistency with all the other functions that overload const/mut)

Is that something that make sense, or is using Pin<&Self> not a common pattern?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.