Skip to content
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
35 changes: 12 additions & 23 deletions internal/src/pin_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use quote::{format_ident, quote, ToTokens};
use syn::{
parse::{End, Nothing, Parse},
parse_quote, parse_quote_spanned,
punctuated::Punctuated,
spanned::Spanned,
visit_mut::VisitMut,
Field, Fields, Generics, Ident, Index, Item, Member, PathSegment, Type, TypePath, Visibility,
WhereClause,
};

use crate::{
Expand Down Expand Up @@ -231,21 +231,11 @@ fn generate_unpin_impl(
generics: &Generics,
fields: &[FieldInfo<'_>],
) -> TokenStream {
let (_, ty_generics, _) = generics.split_for_impl();
let mut generics_with_pin_lt = generics.clone();
generics_with_pin_lt.params.insert(0, parse_quote!('__pin));
generics_with_pin_lt.make_where_clause();
let (
impl_generics_with_pin_lt,
ty_generics_with_pin_lt,
Some(WhereClause {
where_token,
predicates,
}),
) = generics_with_pin_lt.split_for_impl()
else {
unreachable!()
};
let (impl_generics, ty_generics, whr) = generics.split_for_impl();
let predicates = whr
.map(|x| &x.predicates)
.unwrap_or(const { &Punctuated::new() });

let pinned_fields = fields.iter().filter(|f| f.pinned).map(|f| {
let ident = f.member.as_ident();
let ty = &f.field.ty;
Expand All @@ -260,19 +250,18 @@ fn generate_unpin_impl(
dead_code, // The fields below are never used.
non_snake_case // The warning will be emitted on the struct definition.
)]
struct __Unpin #generics_with_pin_lt
#where_token
#predicates
struct __Unpin #generics #whr
{
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
__phantom: ::pin_init::__internal::PhantomInvariant<#ident #ty_generics>,
#(#pinned_fields),*
}

#[doc(hidden)]
impl #impl_generics_with_pin_lt ::core::marker::Unpin for #ident #ty_generics
#where_token
__Unpin #ty_generics_with_pin_lt: ::core::marker::Unpin,
impl #impl_generics ::core::marker::Unpin for #ident #ty_generics
where
// the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds`
// feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>.
for<'__dummy> __Unpin #ty_generics: ::core::marker::Unpin,
#predicates
{}
}
Expand Down
16 changes: 0 additions & 16 deletions src/__internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,6 @@ impl<T: ?Sized> PhantomInvariant<T> {
}
}

/// Zero-sized type used to mark a lifetime as invariant.
///
/// This is a polyfill for the [unstable type] in the standard library of the same name.
///
/// [unstable type]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomInvariantLifetime.html
#[repr(transparent)]
#[derive(Clone, Copy, Default)]
pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>);

impl PhantomInvariantLifetime<'_> {
#[inline(always)]
pub const fn new() -> Self {
Self(PhantomInvariant::new())
}
}

/// Token type to signify successful initialization.
///
/// Can only be constructed via the unsafe [`Self::new`] function. The initializer macros use this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ error[E0277]: `PhantomPinned` cannot be unpinned
--> tests/ui/compile-fail/pin_data/tuple_struct_pinned_field_not_unpin.rs:10:20
|
10 | assert_unpin::<Tuple<usize>>();
| ^^^^^^^^^^^^ within `__Unpin<'_, usize>`, the trait `Unpin` is not implemented for `PhantomPinned`
| ^^^^^^^^^^^^ within `__Unpin<usize>`, the trait `Unpin` is not implemented for `PhantomPinned`
|
= note: consider using the `pin!` macro
consider using `Box::pin` if you need to access the pinned value outside of the current scope
note: required because it appears within the type `__Unpin<'_, usize>`
note: required because it appears within the type `__Unpin<usize>`
--> tests/ui/compile-fail/pin_data/tuple_struct_pinned_field_not_unpin.rs:4:1
|
4 | #[pin_data]
Expand Down
14 changes: 4 additions & 10 deletions tests/ui/expand/many_generics.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,18 @@ const _: () = {
}
}
#[allow(dead_code, non_snake_case)]
struct __Unpin<'__pin, 'a, 'b: 'a, T: Bar<'b> + ?Sized + 'a, const SIZE: usize = 0>
struct __Unpin<'a, 'b: 'a, T: Bar<'b> + ?Sized + 'a, const SIZE: usize = 0>
where
T: Bar<'a, 1>,
{
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
__phantom: ::pin_init::__internal::PhantomInvariant<Foo<'a, 'b, T, SIZE>>,
_pin: PhantomPinned,
}
#[doc(hidden)]
impl<
'__pin,
'a,
'b: 'a,
T: Bar<'b> + ?Sized + 'a,
const SIZE: usize,
> ::core::marker::Unpin for Foo<'a, 'b, T, SIZE>
impl<'a, 'b: 'a, T: Bar<'b> + ?Sized + 'a, const SIZE: usize> ::core::marker::Unpin
for Foo<'a, 'b, T, SIZE>
where
__Unpin<'__pin, 'a, 'b, T, SIZE>: ::core::marker::Unpin,
for<'__dummy> __Unpin<'a, 'b, T, SIZE>: ::core::marker::Unpin,
T: Bar<'a, 1>,
{}
impl<'a, 'b: 'a, T: Bar<'b> + ?Sized + 'a, const SIZE: usize> ::core::ops::Drop
Expand Down
7 changes: 3 additions & 4 deletions tests/ui/expand/pin-data.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,14 @@ const _: () = {
}
}
#[allow(dead_code, non_snake_case)]
struct __Unpin<'__pin> {
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
struct __Unpin {
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
_pin: PhantomPinned,
}
#[doc(hidden)]
impl<'__pin> ::core::marker::Unpin for Foo
impl ::core::marker::Unpin for Foo
where
__Unpin<'__pin>: ::core::marker::Unpin,
for<'__dummy> __Unpin: ::core::marker::Unpin,
{}
trait MustNotImplDrop {}
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
Expand Down
7 changes: 3 additions & 4 deletions tests/ui/expand/pinned_drop.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,14 @@ const _: () = {
}
}
#[allow(dead_code, non_snake_case)]
struct __Unpin<'__pin> {
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
struct __Unpin {
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
_pin: PhantomPinned,
}
#[doc(hidden)]
impl<'__pin> ::core::marker::Unpin for Foo
impl ::core::marker::Unpin for Foo
where
__Unpin<'__pin>: ::core::marker::Unpin,
for<'__dummy> __Unpin: ::core::marker::Unpin,
{}
impl ::core::ops::Drop for Foo {
fn drop(&mut self) {
Expand Down
7 changes: 3 additions & 4 deletions tests/ui/expand/tuple_struct.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,14 @@ const _: () = {
}
}
#[allow(dead_code, non_snake_case)]
struct __Unpin<'__pin, 'a, T: Copy, const N: usize> {
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
struct __Unpin<'a, T: Copy, const N: usize> {
__phantom: ::pin_init::__internal::PhantomInvariant<Foo<'a, T, N>>,
_1: PhantomPinned,
}
#[doc(hidden)]
impl<'__pin, 'a, T: Copy, const N: usize> ::core::marker::Unpin for Foo<'a, T, N>
impl<'a, T: Copy, const N: usize> ::core::marker::Unpin for Foo<'a, T, N>
where
__Unpin<'__pin, 'a, T, N>: ::core::marker::Unpin,
for<'__dummy> __Unpin<'a, T, N>: ::core::marker::Unpin,
{}
trait MustNotImplDrop {}
impl<T: ::core::ops::Drop + ?::core::marker::Sized> MustNotImplDrop for T {}
Expand Down
Loading