Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Sep 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct Struct<T, U> {
}

impl<T, U> Struct<T, U> {
fn foo(mut self: Pin<&mut Self>) {
fn foo(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
Expand Down
19 changes: 2 additions & 17 deletions examples/enum-default-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,8 @@ enum __EnumProjection<'_pin, T, U> {
Unpinned(&'_pin mut U),
}

impl<'_outer_pin, T, U> __EnumProjectionTrait<'_outer_pin, T, U>
for ::core::pin::Pin<&'_outer_pin mut Enum<T, U>>
{
fn project<'_pin>(&'_pin mut self) -> __EnumProjection<'_pin, T, U> {
unsafe {
match self.as_mut().get_unchecked_mut() {
Enum::Pinned(_x0) => __EnumProjection::Pinned(::core::pin::Pin::new_unchecked(_x0)),
Enum::Unpinned(_x0) => __EnumProjection::Unpinned(_x0),
}
}
}
fn project_into(self) -> __EnumProjection<'_outer_pin, T, U> {
impl<T, U> Enum<T, U> {
fn project<'_pin>(self: ::core::pin::Pin<&'_pin mut Self>) -> __EnumProjection<'_pin, T, U> {
unsafe {
match self.get_unchecked_mut() {
Enum::Pinned(_x0) => __EnumProjection::Pinned(::core::pin::Pin::new_unchecked(_x0)),
Expand All @@ -51,11 +41,6 @@ impl<'_outer_pin, T, U> __EnumProjectionTrait<'_outer_pin, T, U>
}
}

trait __EnumProjectionTrait<'_outer_pin, T, U> {
fn project<'_pin>(&'_pin mut self) -> __EnumProjection<'_pin, T, U>;
fn project_into(self) -> __EnumProjection<'_outer_pin, T, U>;
}

// Automatically create the appropriate conditional `Unpin` implementation.
//
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
Expand Down
22 changes: 3 additions & 19 deletions examples/pinned_drop-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,8 @@ struct __FooProjection<'_pin, 'a, T> {
field: ::core::pin::Pin<&'_pin mut T>,
}

impl<'_outer_pin, 'a, T> __FooProjectionTrait<'_outer_pin, 'a, T>
for ::core::pin::Pin<&'_outer_pin mut Foo<'a, T>>
{
fn project<'_pin>(&'_pin mut self) -> __FooProjection<'_pin, 'a, T> {
unsafe {
let Foo { was_dropped, field } = self.as_mut().get_unchecked_mut();
__FooProjection {
was_dropped: was_dropped,
field: ::core::pin::Pin::new_unchecked(field),
}
}
}
fn project_into(self) -> __FooProjection<'_outer_pin, 'a, T> {
impl<'a, T> Foo<'a, T> {
fn project<'_pin>(self: ::core::pin::Pin<&'_pin mut Self>) -> __FooProjection<'_pin, 'a, T> {
unsafe {
let Foo { was_dropped, field } = self.get_unchecked_mut();
__FooProjection {
Expand All @@ -61,11 +50,6 @@ impl<'_outer_pin, 'a, T> __FooProjectionTrait<'_outer_pin, 'a, T>
}
}

trait __FooProjectionTrait<'_outer_pin, 'a, T> {
fn project<'_pin>(&'_pin mut self) -> __FooProjection<'_pin, 'a, T>;
fn project_into(self) -> __FooProjection<'_outer_pin, 'a, T>;
}

#[allow(single_use_lifetimes)]
impl<'a, T> ::core::ops::Drop for Foo<'a, T> {
fn drop(&mut self) {
Expand Down Expand Up @@ -95,7 +79,7 @@ impl<'a, T> ::core::ops::Drop for Foo<'a, T> {
impl<T> ::pin_project::__private::PinnedDrop for Foo<'_, T> {
// Since calling it twice on the same object would be UB,
// this method is unsafe.
unsafe fn drop(mut self: ::core::pin::Pin<&mut Self>) {
unsafe fn drop(self: Pin<&mut Self>) {
**self.project().was_dropped = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/pinned_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct Foo<'a, T> {

#[pinned_drop]
impl<T> PinnedDrop for Foo<'_, T> {
fn drop(mut self: Pin<&mut Self>) {
fn drop(self: Pin<&mut Self>) {
**self.project().was_dropped = true;
}
}
Expand Down
20 changes: 2 additions & 18 deletions examples/struct-default-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,8 @@ struct __StructProjection<'_pin, T, U> {
unpinned: &'_pin mut U,
}

impl<'_outer_pin, T, U> __StructProjectionTrait<'_outer_pin, T, U>
for ::core::pin::Pin<&'_outer_pin mut Struct<T, U>>
{
fn project<'_pin>(&'_pin mut self) -> __StructProjection<'_pin, T, U> {
unsafe {
let Struct { pinned, unpinned } = self.as_mut().get_unchecked_mut();
__StructProjection {
pinned: ::core::pin::Pin::new_unchecked(pinned),
unpinned: unpinned,
}
}
}
fn project_into(self) -> __StructProjection<'_outer_pin, T, U> {
impl<T, U> Struct<T, U> {
fn project<'_pin>(self: ::core::pin::Pin<&'_pin mut Self>) -> __StructProjection<'_pin, T, U> {
unsafe {
let Struct { pinned, unpinned } = self.get_unchecked_mut();
__StructProjection {
Expand All @@ -54,11 +43,6 @@ impl<'_outer_pin, T, U> __StructProjectionTrait<'_outer_pin, T, U>
}
}

trait __StructProjectionTrait<'_outer_pin, T, U> {
fn project<'_pin>(&'_pin mut self) -> __StructProjection<'_pin, T, U>;
fn project_into(self) -> __StructProjection<'_outer_pin, T, U>;
}

// Automatically create the appropriate conditional `Unpin` implementation.
//
// Basically this is equivalent to the following code:
Expand Down
17 changes: 2 additions & 15 deletions examples/unsafe_unpin-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,15 @@ struct __FooProjection<'_pin, T, U> {
unpinned: &'_pin mut U,
}

impl<'_outer_pin, T, U> __FooProjectionTrait<'_outer_pin, T, U>
for ::core::pin::Pin<&'_outer_pin mut Foo<T, U>>
{
fn project<'_pin>(&'_pin mut self) -> __FooProjection<'_pin, T, U> {
unsafe {
let Foo { pinned, unpinned } = self.as_mut().get_unchecked_mut();
__FooProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned: unpinned }
}
}
fn project_into(self) -> __FooProjection<'_outer_pin, T, U> {
impl<T, U> Foo<T, U> {
fn project<'_pin>(self: ::core::pin::Pin<&'_pin mut Self>) -> __FooProjection<'_pin, T, U> {
unsafe {
let Foo { pinned, unpinned } = self.get_unchecked_mut();
__FooProjection { pinned: ::core::pin::Pin::new_unchecked(pinned), unpinned: unpinned }
}
}
}

trait __FooProjectionTrait<'_outer_pin, T, U> {
fn project<'_pin>(&'_pin mut self) -> __FooProjection<'_pin, T, U>;
fn project_into(self) -> __FooProjection<'_outer_pin, T, U>;
}

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

impl<T, U> ::core::marker::Unpin for Foo<T, U> where
Expand Down
53 changes: 14 additions & 39 deletions pin-project-internal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,45 +34,20 @@ use syn::parse::Nothing;
/// the field.
/// - For the other fields, makes the unpinned reference to the field.
///
/// The following methods are implemented on the original `#[pin_project]` type:
/// The following method is implemented on the original `#[pin_project]` type:
///
/// ```
/// # #![feature(arbitrary_self_types)]
/// # use std::pin::Pin;
/// # type ProjectedType = ();
/// # trait ProjectionTrait {
/// fn project(self: &mut Pin<&mut Self>) -> ProjectedType;
/// fn project_into(self: Pin<&mut Self>) -> ProjectedType;
/// # trait Projection {
/// fn project(self: Pin<&mut Self>) -> ProjectedType;
/// # }
/// ```
///
/// The `project` method takes a mutable reference to a pinned
/// type, and returns a projection struct. This is the method
/// you'll usually want to use - since it takes a mutable reference,
/// it can be called multiple times, and allows you to use
/// the original Pin type later on (e.g. to call [`Pin::set`]).
///
/// The `project_into` type takes a pinned type by value (consuming it),
/// and returns a projection struct. The difference between this and the `project`
/// method lies in the lifetime. While the type returned by `project` only lives
/// as long as the 'outer' mutable reference, the type returned by this method
/// lives for as long as the original Pin. This can be useful when returning a pin
/// projection from a method:
///
/// ```
/// # use pin_project::pin_project;
/// # use std::pin::Pin;
/// # #[pin_project]
/// # struct Struct<T> {
/// # #[pin]
/// # pinned: T,
/// # }
/// # impl<T> Struct<T> {
/// fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
/// self.project_into().pinned
/// }
/// # }
/// ```
/// If you want to call the `project` method multiple times or later use the
/// original Pin type, it needs to use [`.as_mut()`][`Pin::as_mut`] to avoid
/// consuming the `Pin`.
///
/// ## Safety
///
Expand Down Expand Up @@ -147,7 +122,7 @@ use syn::parse::Nothing;
/// }
///
/// impl<T, U> Foo<T, U> {
/// fn baz(mut self: Pin<&mut Self>) {
/// 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
Expand All @@ -170,7 +145,7 @@ use syn::parse::Nothing;
/// }
///
/// impl<T, U> Foo<T, U> {
/// fn baz(mut self: Pin<&mut Self>) {
/// 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
Expand Down Expand Up @@ -259,7 +234,7 @@ use syn::parse::Nothing;
/// }
///
/// impl<T, U> Foo<T, U> {
/// fn baz(mut self: Pin<&mut Self>) {
/// fn baz(self: Pin<&mut Self>) {
/// let this = self.project();
/// let _: Pin<&mut T> = this.future;
/// let _: &mut U = this.field;
Expand All @@ -277,7 +252,7 @@ use syn::parse::Nothing;
/// struct Foo<T, U>(#[pin] T, U);
///
/// impl<T, U> Foo<T, U> {
/// fn baz(mut self: Pin<&mut Self>) {
/// fn baz(self: Pin<&mut Self>) {
/// let this = self.project();
/// let _: Pin<&mut T> = this.0;
/// let _: &mut U = this.1;
Expand Down Expand Up @@ -316,7 +291,7 @@ use syn::parse::Nothing;
/// # #[cfg(feature = "project_attr")]
/// impl<A, B, C> Foo<A, B, C> {
/// #[project] // Nightly does not need a dummy attribute to the function.
/// fn baz(mut self: Pin<&mut Self>) {
/// fn baz(self: Pin<&mut Self>) {
/// #[project]
/// match self.project() {
/// Foo::Tuple(x, y) => {
Expand Down Expand Up @@ -422,7 +397,7 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
///
/// // impl for the original type
/// impl<T, U> Foo<T, U> {
/// fn bar(mut self: Pin<&mut Self>) {
/// fn bar(self: Pin<&mut Self>) {
/// self.project().baz()
/// }
/// }
Expand Down Expand Up @@ -459,7 +434,7 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
///
/// impl<T, U> Foo<T, U> {
/// #[project] // Nightly does not need a dummy attribute to the function.
/// fn baz(mut self: Pin<&mut Self>) {
/// fn baz(self: Pin<&mut Self>) {
/// #[project]
/// let Foo { future, field } = self.project();
///
Expand Down Expand Up @@ -489,7 +464,7 @@ pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
///
/// impl<A, B, C> Foo<A, B, C> {
/// #[project] // Nightly does not need a dummy attribute to the function.
/// fn baz(mut self: Pin<&mut Self>) {
/// fn baz(self: Pin<&mut Self>) {
/// #[project]
/// match self.project() {
/// Foo::Tuple(x, y) => {
Expand Down
Loading