diff --git a/internal/src/pin_data.rs b/internal/src/pin_data.rs index 163a31ed..91f62dd7 100644 --- a/internal/src/pin_data.rs +++ b/internal/src/pin_data.rs @@ -169,10 +169,8 @@ fn generate_unpin_impl( #where_token #predicates { - __phantom_pin: ::core::marker::PhantomData &'__pin ()>, - __phantom: ::core::marker::PhantomData< - fn(#ident #ty_generics) -> #ident #ty_generics - >, + __phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>, + __phantom: ::pin_init::__internal::PhantomInvariant<#ident #ty_generics>, #(#pinned_fields),* } @@ -427,9 +425,7 @@ fn generate_the_pin_data( #vis struct __ThePinData #generics #whr { - __phantom: ::core::marker::PhantomData< - fn(#ident #ty_generics) -> #ident #ty_generics - >, + __phantom: ::pin_init::__internal::PhantomInvariant<#ident #ty_generics>, } impl #impl_generics ::core::clone::Clone for __ThePinData #ty_generics @@ -458,7 +454,7 @@ fn generate_the_pin_data( type PinData = __ThePinData #ty_generics; unsafe fn __pin_data() -> Self::PinData { - __ThePinData { __phantom: ::core::marker::PhantomData } + __ThePinData { __phantom: ::pin_init::__internal::PhantomInvariant::new() } } } diff --git a/src/__internal.rs b/src/__internal.rs index 5720a621..e54d90a4 100644 --- a/src/__internal.rs +++ b/src/__internal.rs @@ -7,20 +7,62 @@ use super::*; -/// See the [nomicon] for what subtyping is. See also [this table]. +/// Zero-sized type used to mark a type as invariant. +/// +/// This is a polyfill for the [unstable type] in the standard library of the same name. /// -/// The reason for not using `PhantomData<*mut T>` is that that type never implements [`Send`] and -/// [`Sync`]. Hence `fn(*mut T) -> *mut T` is used, as that type always implements them. +/// See the [nomicon] for what subtyping is. See also [this table]. /// +/// [unstable type]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomInvariant.html /// [nomicon]: https://doc.rust-lang.org/nomicon/subtyping.html /// [this table]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns -pub(crate) type Invariant = PhantomData *mut T>; +#[repr(transparent)] +pub struct PhantomInvariant(PhantomData T>); + +impl Clone for PhantomInvariant { + #[inline(always)] + fn clone(&self) -> Self { + *self + } +} + +impl Copy for PhantomInvariant {} + +impl Default for PhantomInvariant { + #[inline(always)] + fn default() -> Self { + Self::new() + } +} + +impl PhantomInvariant { + #[inline(always)] + pub const fn new() -> Self { + Self(PhantomData) + } +} + +/// 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()) + } +} /// Module-internal type implementing `PinInit` and `Init`. /// /// It is unsafe to create this type, since the closure needs to fulfill the same safety /// requirement as the `__pinned_init`/`__init` functions. -pub(crate) struct InitClosure(pub(crate) F, pub(crate) Invariant<(E, T)>); +pub(crate) struct InitClosure(pub(crate) F, pub(crate) PhantomInvariant<(E, T)>); // SAFETY: While constructing the `InitClosure`, the user promised that it upholds the // `__init` invariants. @@ -126,7 +168,7 @@ pub unsafe trait InitData: Copy { } } -pub struct AllData(Invariant); +pub struct AllData(PhantomInvariant); impl Clone for AllData { fn clone(&self) -> Self { @@ -146,7 +188,7 @@ unsafe impl HasInitData for T { type InitData = AllData; unsafe fn __init_data() -> Self::InitData { - AllData(PhantomData) + AllData(PhantomInvariant::new()) } } diff --git a/src/lib.rs b/src/lib.rs index 9b76cf55..063ba0cd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -947,12 +947,12 @@ pub unsafe trait PinInit: Sized { where F: FnOnce(Pin<&mut T>) -> Result<(), E>, { - ChainPinInit(self, f, PhantomData) + ChainPinInit(self, f, __internal::PhantomInvariant::new()) } } /// An initializer returned by [`PinInit::pin_chain`]. -pub struct ChainPinInit(I, F, __internal::Invariant<(E, T)>); +pub struct ChainPinInit(I, F, __internal::PhantomInvariant<(E, T)>); // SAFETY: The `__pinned_init` function is implemented such that it // - returns `Ok(())` on successful initialization, @@ -1055,12 +1055,12 @@ pub unsafe trait Init: PinInit { where F: FnOnce(&mut T) -> Result<(), E>, { - ChainInit(self, f, PhantomData) + ChainInit(self, f, __internal::PhantomInvariant::new()) } } /// An initializer returned by [`Init::chain`]. -pub struct ChainInit(I, F, __internal::Invariant<(E, T)>); +pub struct ChainInit(I, F, __internal::PhantomInvariant<(E, T)>); // SAFETY: The `__init` function is implemented such that it // - returns `Ok(())` on successful initialization, @@ -1108,7 +1108,7 @@ where pub const unsafe fn pin_init_from_closure( f: impl FnOnce(*mut T) -> Result<(), E>, ) -> impl PinInit { - __internal::InitClosure(f, PhantomData) + __internal::InitClosure(f, __internal::PhantomInvariant::new()) } /// Creates a new [`Init`] from the given closure. @@ -1127,7 +1127,7 @@ pub const unsafe fn pin_init_from_closure( pub const unsafe fn init_from_closure( f: impl FnOnce(*mut T) -> Result<(), E>, ) -> impl Init { - __internal::InitClosure(f, PhantomData) + __internal::InitClosure(f, __internal::PhantomInvariant::new()) } /// Changes the to be initialized type. diff --git a/tests/ui/expand/many_generics.expanded.rs b/tests/ui/expand/many_generics.expanded.rs index f6962e3a..c092e40b 100644 --- a/tests/ui/expand/many_generics.expanded.rs +++ b/tests/ui/expand/many_generics.expanded.rs @@ -55,9 +55,7 @@ const _: () = { where T: Bar<'a, 1>, { - __phantom: ::core::marker::PhantomData< - fn(Foo<'a, 'b, T, SIZE>) -> Foo<'a, 'b, T, SIZE>, - >, + __phantom: ::pin_init::__internal::PhantomInvariant>, } impl<'a, 'b: 'a, T: Bar<'b> + ?Sized + 'a, const SIZE: usize> ::core::clone::Clone for __ThePinData<'a, 'b, T, SIZE> @@ -161,7 +159,7 @@ const _: () = { type PinData = __ThePinData<'a, 'b, T, SIZE>; unsafe fn __pin_data() -> Self::PinData { __ThePinData { - __phantom: ::core::marker::PhantomData, + __phantom: ::pin_init::__internal::PhantomInvariant::new(), } } } @@ -181,10 +179,8 @@ const _: () = { where T: Bar<'a, 1>, { - __phantom_pin: ::core::marker::PhantomData &'__pin ()>, - __phantom: ::core::marker::PhantomData< - fn(Foo<'a, 'b, T, SIZE>) -> Foo<'a, 'b, T, SIZE>, - >, + __phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>, + __phantom: ::pin_init::__internal::PhantomInvariant>, _pin: PhantomPinned, } #[doc(hidden)] diff --git a/tests/ui/expand/pin-data.expanded.rs b/tests/ui/expand/pin-data.expanded.rs index fb59d866..6de94f38 100644 --- a/tests/ui/expand/pin-data.expanded.rs +++ b/tests/ui/expand/pin-data.expanded.rs @@ -35,7 +35,7 @@ impl Foo { const _: () = { #[doc(hidden)] struct __ThePinData { - __phantom: ::core::marker::PhantomData Foo>, + __phantom: ::pin_init::__internal::PhantomInvariant, } impl ::core::clone::Clone for __ThePinData { fn clone(&self) -> Self { @@ -94,7 +94,7 @@ const _: () = { type PinData = __ThePinData; unsafe fn __pin_data() -> Self::PinData { __ThePinData { - __phantom: ::core::marker::PhantomData, + __phantom: ::pin_init::__internal::PhantomInvariant::new(), } } } @@ -103,8 +103,8 @@ const _: () = { } #[allow(dead_code)] struct __Unpin<'__pin> { - __phantom_pin: ::core::marker::PhantomData &'__pin ()>, - __phantom: ::core::marker::PhantomData Foo>, + __phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>, + __phantom: ::pin_init::__internal::PhantomInvariant, _pin: PhantomPinned, } #[doc(hidden)] diff --git a/tests/ui/expand/pinned_drop.expanded.rs b/tests/ui/expand/pinned_drop.expanded.rs index 5e0f1250..183cd3f3 100644 --- a/tests/ui/expand/pinned_drop.expanded.rs +++ b/tests/ui/expand/pinned_drop.expanded.rs @@ -35,7 +35,7 @@ impl Foo { const _: () = { #[doc(hidden)] struct __ThePinData { - __phantom: ::core::marker::PhantomData Foo>, + __phantom: ::pin_init::__internal::PhantomInvariant, } impl ::core::clone::Clone for __ThePinData { fn clone(&self) -> Self { @@ -94,7 +94,7 @@ const _: () = { type PinData = __ThePinData; unsafe fn __pin_data() -> Self::PinData { __ThePinData { - __phantom: ::core::marker::PhantomData, + __phantom: ::pin_init::__internal::PhantomInvariant::new(), } } } @@ -103,8 +103,8 @@ const _: () = { } #[allow(dead_code)] struct __Unpin<'__pin> { - __phantom_pin: ::core::marker::PhantomData &'__pin ()>, - __phantom: ::core::marker::PhantomData Foo>, + __phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>, + __phantom: ::pin_init::__internal::PhantomInvariant, _pin: PhantomPinned, } #[doc(hidden)]