Skip to content
Open
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
12 changes: 4 additions & 8 deletions internal/src/pin_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,8 @@ fn generate_unpin_impl(
#where_token
#predicates
{
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__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),*
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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() }
}
}

Expand Down
56 changes: 49 additions & 7 deletions src/__internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> = PhantomData<fn(*mut T) -> *mut T>;
#[repr(transparent)]
pub struct PhantomInvariant<T: ?Sized>(PhantomData<fn(T) -> T>);

impl<T: ?Sized> Clone for PhantomInvariant<T> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}

impl<T: ?Sized> Copy for PhantomInvariant<T> {}

impl<T: ?Sized> Default for PhantomInvariant<T> {
#[inline(always)]
fn default() -> Self {
Self::new()
}
}

impl<T: ?Sized> PhantomInvariant<T> {
#[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<F, T: ?Sized, E>(pub(crate) F, pub(crate) Invariant<(E, T)>);
pub(crate) struct InitClosure<F, T: ?Sized, E>(pub(crate) F, pub(crate) PhantomInvariant<(E, T)>);

// SAFETY: While constructing the `InitClosure`, the user promised that it upholds the
// `__init` invariants.
Expand Down Expand Up @@ -126,7 +168,7 @@ pub unsafe trait InitData: Copy {
}
}

pub struct AllData<T: ?Sized>(Invariant<T>);
pub struct AllData<T: ?Sized>(PhantomInvariant<T>);

impl<T: ?Sized> Clone for AllData<T> {
fn clone(&self) -> Self {
Expand All @@ -146,7 +188,7 @@ unsafe impl<T: ?Sized> HasInitData for T {
type InitData = AllData<T>;

unsafe fn __init_data() -> Self::InitData {
AllData(PhantomData)
AllData(PhantomInvariant::new())
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,12 +947,12 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: 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, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);
pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::PhantomInvariant<(E, T)>);

// SAFETY: The `__pinned_init` function is implemented such that it
// - returns `Ok(())` on successful initialization,
Expand Down Expand Up @@ -1055,12 +1055,12 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
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, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);
pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::PhantomInvariant<(E, T)>);

// SAFETY: The `__init` function is implemented such that it
// - returns `Ok(())` on successful initialization,
Expand Down Expand Up @@ -1108,7 +1108,7 @@ where
pub const unsafe fn pin_init_from_closure<T: ?Sized, E>(
f: impl FnOnce(*mut T) -> Result<(), E>,
) -> impl PinInit<T, E> {
__internal::InitClosure(f, PhantomData)
__internal::InitClosure(f, __internal::PhantomInvariant::new())
}

/// Creates a new [`Init<T, E>`] from the given closure.
Expand All @@ -1127,7 +1127,7 @@ pub const unsafe fn pin_init_from_closure<T: ?Sized, E>(
pub const unsafe fn init_from_closure<T: ?Sized, E>(
f: impl FnOnce(*mut T) -> Result<(), E>,
) -> impl Init<T, E> {
__internal::InitClosure(f, PhantomData)
__internal::InitClosure(f, __internal::PhantomInvariant::new())
}

/// Changes the to be initialized type.
Expand Down
12 changes: 4 additions & 8 deletions tests/ui/expand/many_generics.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Foo<'a, 'b, T, SIZE>>,
}
impl<'a, 'b: 'a, T: Bar<'b> + ?Sized + 'a, const SIZE: usize> ::core::clone::Clone
for __ThePinData<'a, 'b, T, SIZE>
Expand Down Expand Up @@ -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(),
}
}
}
Expand All @@ -181,10 +179,8 @@ const _: () = {
where
T: Bar<'a, 1>,
{
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__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<Foo<'a, 'b, T, SIZE>>,
_pin: PhantomPinned,
}
#[doc(hidden)]
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/expand/pin-data.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl Foo {
const _: () = {
#[doc(hidden)]
struct __ThePinData {
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
}
impl ::core::clone::Clone for __ThePinData {
fn clone(&self) -> Self {
Expand Down Expand Up @@ -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(),
}
}
}
Expand All @@ -103,8 +103,8 @@ const _: () = {
}
#[allow(dead_code)]
struct __Unpin<'__pin> {
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
_pin: PhantomPinned,
}
#[doc(hidden)]
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/expand/pinned_drop.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl Foo {
const _: () = {
#[doc(hidden)]
struct __ThePinData {
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
}
impl ::core::clone::Clone for __ThePinData {
fn clone(&self) -> Self {
Expand Down Expand Up @@ -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(),
}
}
}
Expand All @@ -103,8 +103,8 @@ const _: () = {
}
#[allow(dead_code)]
struct __Unpin<'__pin> {
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
_pin: PhantomPinned,
}
#[doc(hidden)]
Expand Down
Loading