Skip to content

Commit

Permalink
Merge #90
Browse files Browse the repository at this point in the history
90: Change the argument type of project method back to `self: Pin<&mut Self>` r=taiki-e a=taiki-e

Closes #89


Co-authored-by: Taiki Endo <[email protected]>
  • Loading branch information
bors[bot] and taiki-e authored Sep 18, 2019
2 parents c01416d + 97bc267 commit ddc0122
Show file tree
Hide file tree
Showing 18 changed files with 106 additions and 272 deletions.
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

0 comments on commit ddc0122

Please sign in to comment.