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

Remove lifetime from wrapper types and impl generics #358

Closed
wants to merge 1 commit into from
Closed
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
18 changes: 9 additions & 9 deletions examples/enum-default-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,22 @@ const _: () = {
//
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
// for details.
struct __Enum<'pin, T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
'pin,
(::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
>,
struct __Enum<T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<(
::pin_project::__private::PhantomData<T>,
::pin_project::__private::PhantomData<U>,
)>,
__field0: T,
}
impl<'pin, T, U> ::pin_project::__private::Unpin for Enum<T, U> where
::pin_project::__private::PinnedFieldsOf<__Enum<'pin, T, U>>:
impl<T, U> ::pin_project::__private::Unpin for Enum<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Enum<T, U>>:
::pin_project::__private::Unpin
{
}
// A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
#[doc(hidden)]
unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Enum<T, U> where
::pin_project::__private::PinnedFieldsOf<__Enum<'pin, T, U>>:
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Enum<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Enum<T, U>>:
::pin_project::__private::Unpin
{
}
Expand Down
12 changes: 6 additions & 6 deletions examples/not_unpin-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ const _: () = {
// See https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282
// for details.
#[doc(hidden)]
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
::pin_project::__private::PinnedFieldsOf<
::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>,
impl<T, U> ::pin_project::__private::Unpin for Struct<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<
::pin_project::__private::Wrapper<::pin_project::__private::PhantomPinned>,
>: ::pin_project::__private::Unpin
{
}
Expand All @@ -109,9 +109,9 @@ const _: () = {
// impl, they'll get a "conflicting implementations of trait" error when
// coherence checks are run.
#[doc(hidden)]
unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
::pin_project::__private::PinnedFieldsOf<
::pin_project::__private::Wrapper<'pin, ::pin_project::__private::PhantomPinned>,
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<
::pin_project::__private::Wrapper<::pin_project::__private::PhantomPinned>,
>: ::pin_project::__private::Unpin
{
}
Expand Down
12 changes: 6 additions & 6 deletions examples/pinned_drop-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,20 @@ const _: () = {
//
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
// for details.
pub struct __Struct<'pin, 'a, T> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<'pin, (T)>,
pub struct __Struct<'a, T> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<(T)>,
__field0: T,
__lifetime0: &'a (),
}
impl<'pin, 'a, T> ::pin_project::__private::Unpin for Struct<'a, T> where
::pin_project::__private::PinnedFieldsOf<__Struct<'pin, 'a, T>>:
impl<'a, T> ::pin_project::__private::Unpin for Struct<'a, T> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Struct<'a, T>>:
::pin_project::__private::Unpin
{
}
// A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
#[doc(hidden)]
unsafe impl<'pin, 'a, T> ::pin_project::UnsafeUnpin for Struct<'a, T> where
::pin_project::__private::PinnedFieldsOf<__Struct<'pin, 'a, T>>:
unsafe impl<'a, T> ::pin_project::UnsafeUnpin for Struct<'a, T> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Struct<'a, T>>:
::pin_project::__private::Unpin
{
}
Expand Down
18 changes: 9 additions & 9 deletions examples/project_replace-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,22 +129,22 @@ const _: () = {
//
// See ./struct-default-expanded.rs and https://github.com/taiki-e/pin-project/pull/53.
// for details.
struct __Struct<'pin, T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
'pin,
(::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
>,
struct __Struct<T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<(
::pin_project::__private::PhantomData<T>,
::pin_project::__private::PhantomData<U>,
)>,
__field0: T,
}
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
::pin_project::__private::PinnedFieldsOf<__Struct<'pin, T, U>>:
impl<T, U> ::pin_project::__private::Unpin for Struct<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Struct<T, U>>:
::pin_project::__private::Unpin
{
}
// A dummy impl of `UnsafeUnpin`, to ensure that the user cannot implement it.
#[doc(hidden)]
unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
::pin_project::__private::PinnedFieldsOf<__Struct<'pin, T, U>>:
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Struct<T, U>>:
::pin_project::__private::Unpin
{
}
Expand Down
18 changes: 9 additions & 9 deletions examples/struct-default-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ const _: () = {
// regardless of the privacy of the types of their fields.
//
// See also https://github.com/taiki-e/pin-project/pull/53.
struct __Struct<'pin, T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<
'pin,
(::pin_project::__private::PhantomData<T>, ::pin_project::__private::PhantomData<U>),
>,
struct __Struct<T, U> {
__pin_project_use_generics: ::pin_project::__private::AlwaysUnpin<(
::pin_project::__private::PhantomData<T>,
::pin_project::__private::PhantomData<U>,
)>,
__field0: T,
}
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
::pin_project::__private::PinnedFieldsOf<__Struct<'pin, T, U>>:
impl<T, U> ::pin_project::__private::Unpin for Struct<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Struct<T, U>>:
::pin_project::__private::Unpin
{
}
Expand All @@ -140,8 +140,8 @@ const _: () = {
// impl, they'll get a "conflicting implementations of trait" error when
// coherence checks are run.
#[doc(hidden)]
unsafe impl<'pin, T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
::pin_project::__private::PinnedFieldsOf<__Struct<'pin, T, U>>:
unsafe impl<T, U> ::pin_project::UnsafeUnpin for Struct<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<__Struct<T, U>>:
::pin_project::__private::Unpin
{
}
Expand Down
4 changes: 2 additions & 2 deletions examples/unsafe_unpin-expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ const _: () = {
}

// Implement `Unpin` via `UnsafeUnpin`.
impl<'pin, T, U> ::pin_project::__private::Unpin for Struct<T, U> where
::pin_project::__private::PinnedFieldsOf<::pin_project::__private::Wrapper<'pin, Self>>:
impl<T, U> ::pin_project::__private::Unpin for Struct<T, U> where
for<'pin> ::pin_project::__private::PinnedFieldsOf<::pin_project::__private::Wrapper<Self>>:
::pin_project::UnsafeUnpin
{
}
Expand Down
53 changes: 24 additions & 29 deletions pin-project-internal/src/pin_project/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,20 +687,18 @@ fn proj_own_body(
fn make_unpin_impl(cx: &Context<'_>) -> TokenStream {
match cx.unpin_impl {
UnpinImpl::Unsafe(span) => {
let mut proj_generics = cx.proj.generics.clone();
let mut where_clause = cx.orig.generics.where_clause.clone().unwrap();
let orig_ident = cx.orig.ident;
let (impl_generics, ty_generics, _) = cx.orig.generics.split_for_impl();
let lifetime = &cx.proj.lifetime;

// Make the error message highlight `UnsafeUnpin` argument.
proj_generics.make_where_clause().predicates.push(parse_quote_spanned! { span =>
::pin_project::__private::PinnedFieldsOf<
_pin_project::__private::Wrapper<#lifetime, Self>
where_clause.predicates.push(parse_quote_spanned! { span =>
for<#lifetime> ::pin_project::__private::PinnedFieldsOf<
_pin_project::__private::Wrapper<Self>
>: _pin_project::UnsafeUnpin
});

let (impl_generics, _, where_clause) = proj_generics.split_for_impl();
let ty_generics = cx.orig.generics.split_for_impl().1;

quote_spanned! { span =>
impl #impl_generics _pin_project::__private::Unpin for #orig_ident #ty_generics
#where_clause
Expand All @@ -709,27 +707,27 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream {
}
}
UnpinImpl::Negative(span) => {
let mut proj_generics = cx.proj.generics.clone();
let mut where_clause = cx.orig.generics.where_clause.clone().unwrap();
let orig_ident = cx.orig.ident;
let (impl_generics, ty_generics, _) = cx.orig.generics.split_for_impl();
let lifetime = &cx.proj.lifetime;

proj_generics.make_where_clause().predicates.push(parse_quote! {
::pin_project::__private::PinnedFieldsOf<_pin_project::__private::Wrapper<
#lifetime, _pin_project::__private::PhantomPinned
>>: _pin_project::__private::Unpin
where_clause.predicates.push(parse_quote! {
// TODO: Using `<unsized type>: Sized` here allow emulating real negative_impls...
// https://github.com/taiki-e/pin-project/issues/340#issuecomment-2428002670
for<#lifetime> ::pin_project::__private::PinnedFieldsOf<
_pin_project::__private::Wrapper<_pin_project::__private::PhantomPinned>
>: _pin_project::__private::Unpin
});

let (proj_impl_generics, _, proj_where_clause) = proj_generics.split_for_impl();
let ty_generics = cx.orig.generics.split_for_impl().1;

// For interoperability with `forbid(unsafe_code)`, `unsafe` token should be
// call-site span.
let unsafety = <Token![unsafe]>::default();
quote_spanned! { span =>
#[doc(hidden)]
impl #proj_impl_generics _pin_project::__private::Unpin
impl #impl_generics _pin_project::__private::Unpin
for #orig_ident #ty_generics
#proj_where_clause
#where_clause
{
}

Expand All @@ -740,9 +738,9 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream {
// impl, they'll get a "conflicting implementations of trait" error when
// coherence checks are run.
#[doc(hidden)]
#unsafety impl #proj_impl_generics _pin_project::UnsafeUnpin
#unsafety impl #impl_generics _pin_project::UnsafeUnpin
for #orig_ident #ty_generics
#proj_where_clause
#where_clause
{
}
}
Expand Down Expand Up @@ -790,12 +788,11 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream {
let vis = cx.orig.vis;
let lifetime = &cx.proj.lifetime;
let type_params = cx.orig.generics.type_params().map(|t| &t.ident);
let proj_generics = &cx.proj.generics;
let (proj_impl_generics, proj_ty_generics, _) = proj_generics.split_for_impl();
let (_, ty_generics, where_clause) = cx.orig.generics.split_for_impl();
let orig_generics = &cx.orig.generics;
let (impl_generics, ty_generics, where_clause) = cx.orig.generics.split_for_impl();

full_where_clause.predicates.push(parse_quote! {
::pin_project::__private::PinnedFieldsOf<#struct_ident #proj_ty_generics>:
for<#lifetime> ::pin_project::__private::PinnedFieldsOf<#struct_ident #ty_generics>:
_pin_project::__private::Unpin
});

Expand All @@ -811,17 +808,16 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream {
// However, we ensure that the user can never actually reference
// this 'public' type by creating this type in the inside of `const`.
#[allow(missing_debug_implementations)]
#vis struct #struct_ident #proj_generics #where_clause {
#vis struct #struct_ident #orig_generics #where_clause {
__pin_project_use_generics: _pin_project::__private::AlwaysUnpin<
#lifetime, (#(_pin_project::__private::PhantomData<#type_params>),*)
(#(_pin_project::__private::PhantomData<#type_params>),*)
>,

#(#fields,)*
#(#lifetime_fields,)*
}

impl #proj_impl_generics _pin_project::__private::Unpin
for #orig_ident #ty_generics
impl #impl_generics _pin_project::__private::Unpin for #orig_ident #ty_generics
#full_where_clause
{
}
Expand All @@ -833,8 +829,7 @@ fn make_unpin_impl(cx: &Context<'_>) -> TokenStream {
// impl, they'll get a "conflicting implementations of trait" error when
// coherence checks are run.
#[doc(hidden)]
unsafe impl #proj_impl_generics _pin_project::UnsafeUnpin
for #orig_ident #ty_generics
unsafe impl #impl_generics _pin_project::UnsafeUnpin for #orig_ident #ty_generics
#full_where_clause
{
}
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ pub mod __private {
// provide an impl of `Unpin`
#[doc(hidden)]
#[allow(dead_code)]
pub struct Wrapper<'a, T: ?Sized>(PhantomData<&'a ()>, T);
pub struct Wrapper<T: ?Sized>(T);
// SAFETY: `T` implements UnsafeUnpin.
unsafe impl<T: ?Sized + UnsafeUnpin> UnsafeUnpin for Wrapper<'_, T> {}
unsafe impl<T: ?Sized + UnsafeUnpin> UnsafeUnpin for Wrapper<T> {}

// Workaround for issue on unstable negative_impls feature that allows unsound overlapping Unpin
// implementations and rustc bug that leaks unstable negative_impls into stable.
Expand All @@ -300,8 +300,8 @@ pub mod __private {
//
// See https://github.com/taiki-e/pin-project/pull/53 for more details.
#[doc(hidden)]
pub struct AlwaysUnpin<'a, T>(PhantomData<&'a ()>, PhantomData<T>);
impl<T> Unpin for AlwaysUnpin<'_, T> {}
pub struct AlwaysUnpin<T>(PhantomData<T>);
impl<T> Unpin for AlwaysUnpin<T> {}

// This is an internal helper used to ensure a value is dropped.
#[doc(hidden)]
Expand Down
15 changes: 7 additions & 8 deletions tests/expand/default/enum.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,8 @@ const _: () = {
}
}
#[allow(missing_debug_implementations)]
struct __Enum<'pin, T, U> {
struct __Enum<T, U> {
__pin_project_use_generics: _pin_project::__private::AlwaysUnpin<
'pin,
(
_pin_project::__private::PhantomData<T>,
_pin_project::__private::PhantomData<U>,
Expand All @@ -129,17 +128,17 @@ const _: () = {
__field0: T,
__field1: T,
}
impl<'pin, T, U> _pin_project::__private::Unpin for Enum<T, U>
impl<T, U> _pin_project::__private::Unpin for Enum<T, U>
where
::pin_project::__private::PinnedFieldsOf<
__Enum<'pin, T, U>,
for<'pin> ::pin_project::__private::PinnedFieldsOf<
__Enum<T, U>,
>: _pin_project::__private::Unpin,
{}
#[doc(hidden)]
unsafe impl<'pin, T, U> _pin_project::UnsafeUnpin for Enum<T, U>
unsafe impl<T, U> _pin_project::UnsafeUnpin for Enum<T, U>
where
::pin_project::__private::PinnedFieldsOf<
__Enum<'pin, T, U>,
for<'pin> ::pin_project::__private::PinnedFieldsOf<
__Enum<T, U>,
>: _pin_project::__private::Unpin,
{}
trait EnumMustNotImplDrop {}
Expand Down
15 changes: 7 additions & 8 deletions tests/expand/default/struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,27 +78,26 @@ const _: () = {
let _ = &this.unpinned;
}
#[allow(missing_debug_implementations)]
struct __Struct<'pin, T, U> {
struct __Struct<T, U> {
__pin_project_use_generics: _pin_project::__private::AlwaysUnpin<
'pin,
(
_pin_project::__private::PhantomData<T>,
_pin_project::__private::PhantomData<U>,
),
>,
__field0: T,
}
impl<'pin, T, U> _pin_project::__private::Unpin for Struct<T, U>
impl<T, U> _pin_project::__private::Unpin for Struct<T, U>
where
::pin_project::__private::PinnedFieldsOf<
__Struct<'pin, T, U>,
for<'pin> ::pin_project::__private::PinnedFieldsOf<
__Struct<T, U>,
>: _pin_project::__private::Unpin,
{}
#[doc(hidden)]
unsafe impl<'pin, T, U> _pin_project::UnsafeUnpin for Struct<T, U>
unsafe impl<T, U> _pin_project::UnsafeUnpin for Struct<T, U>
where
::pin_project::__private::PinnedFieldsOf<
__Struct<'pin, T, U>,
for<'pin> ::pin_project::__private::PinnedFieldsOf<
__Struct<T, U>,
>: _pin_project::__private::Unpin,
{}
trait StructMustNotImplDrop {}
Expand Down
Loading