Skip to content

Commit 5a4877d

Browse files
authored
Merge pull request #150 from Rust-for-Linux/dev/invariant
internal: add `PhantomInvariant` and `PhantomInvariantLifetime`
2 parents 0a1f2a3 + 483a31d commit 5a4877d

6 files changed

Lines changed: 71 additions & 37 deletions

File tree

internal/src/pin_data.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,8 @@ fn generate_unpin_impl(
180180
#where_token
181181
#predicates
182182
{
183-
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
184-
__phantom: ::core::marker::PhantomData<
185-
fn(#ident #ty_generics) -> #ident #ty_generics
186-
>,
183+
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
184+
__phantom: ::pin_init::__internal::PhantomInvariant<#ident #ty_generics>,
187185
#(#pinned_fields),*
188186
}
189187

@@ -434,9 +432,7 @@ fn generate_the_pin_data(
434432
#vis struct __ThePinData #generics
435433
#whr
436434
{
437-
__phantom: ::core::marker::PhantomData<
438-
fn(#struct_name #ty_generics) -> #struct_name #ty_generics
439-
>,
435+
__phantom: ::pin_init::__internal::PhantomInvariant<#struct_name #ty_generics>,
440436
}
441437

442438
impl #impl_generics ::core::clone::Clone for __ThePinData #ty_generics
@@ -465,7 +461,7 @@ fn generate_the_pin_data(
465461
type PinData = __ThePinData #ty_generics;
466462

467463
unsafe fn __pin_data() -> Self::PinData {
468-
__ThePinData { __phantom: ::core::marker::PhantomData }
464+
__ThePinData { __phantom: ::pin_init::__internal::PhantomInvariant::new() }
469465
}
470466
}
471467

src/__internal.rs

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,62 @@
77
88
use super::*;
99

10-
/// See the [nomicon] for what subtyping is. See also [this table].
10+
/// Zero-sized type used to mark a type as invariant.
11+
///
12+
/// This is a polyfill for the [unstable type] in the standard library of the same name.
1113
///
12-
/// The reason for not using `PhantomData<*mut T>` is that that type never implements [`Send`] and
13-
/// [`Sync`]. Hence `fn(*mut T) -> *mut T` is used, as that type always implements them.
14+
/// See the [nomicon] for what subtyping is. See also [this table].
1415
///
16+
/// [unstable type]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomInvariant.html
1517
/// [nomicon]: https://doc.rust-lang.org/nomicon/subtyping.html
1618
/// [this table]: https://doc.rust-lang.org/nomicon/phantom-data.html#table-of-phantomdata-patterns
17-
pub(crate) type Invariant<T> = PhantomData<fn(*mut T) -> *mut T>;
19+
#[repr(transparent)]
20+
pub struct PhantomInvariant<T: ?Sized>(PhantomData<fn(T) -> T>);
21+
22+
impl<T: ?Sized> Clone for PhantomInvariant<T> {
23+
#[inline(always)]
24+
fn clone(&self) -> Self {
25+
*self
26+
}
27+
}
28+
29+
impl<T: ?Sized> Copy for PhantomInvariant<T> {}
30+
31+
impl<T: ?Sized> Default for PhantomInvariant<T> {
32+
#[inline(always)]
33+
fn default() -> Self {
34+
Self::new()
35+
}
36+
}
37+
38+
impl<T: ?Sized> PhantomInvariant<T> {
39+
#[inline(always)]
40+
pub const fn new() -> Self {
41+
Self(PhantomData)
42+
}
43+
}
44+
45+
/// Zero-sized type used to mark a lifetime as invariant.
46+
///
47+
/// This is a polyfill for the [unstable type] in the standard library of the same name.
48+
///
49+
/// [unstable type]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomInvariantLifetime.html
50+
#[repr(transparent)]
51+
#[derive(Clone, Copy, Default)]
52+
pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>);
53+
54+
impl PhantomInvariantLifetime<'_> {
55+
#[inline(always)]
56+
pub const fn new() -> Self {
57+
Self(PhantomInvariant::new())
58+
}
59+
}
1860

1961
/// Module-internal type implementing `PinInit` and `Init`.
2062
///
2163
/// It is unsafe to create this type, since the closure needs to fulfill the same safety
2264
/// requirement as the `__pinned_init`/`__init` functions.
23-
pub(crate) struct InitClosure<F, T: ?Sized, E>(pub(crate) F, pub(crate) Invariant<(E, T)>);
65+
pub(crate) struct InitClosure<F, T: ?Sized, E>(pub(crate) F, pub(crate) PhantomInvariant<(E, T)>);
2466

2567
// SAFETY: While constructing the `InitClosure`, the user promised that it upholds the
2668
// `__init` invariants.
@@ -126,7 +168,7 @@ pub unsafe trait InitData: Copy {
126168
}
127169
}
128170

129-
pub struct AllData<T: ?Sized>(Invariant<T>);
171+
pub struct AllData<T: ?Sized>(PhantomInvariant<T>);
130172

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

148190
unsafe fn __init_data() -> Self::InitData {
149-
AllData(PhantomData)
191+
AllData(PhantomInvariant::new())
150192
}
151193
}
152194

src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -947,12 +947,12 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
947947
where
948948
F: FnOnce(Pin<&mut T>) -> Result<(), E>,
949949
{
950-
ChainPinInit(self, f, PhantomData)
950+
ChainPinInit(self, f, __internal::PhantomInvariant::new())
951951
}
952952
}
953953

954954
/// An initializer returned by [`PinInit::pin_chain`].
955-
pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);
955+
pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::PhantomInvariant<(E, T)>);
956956

957957
// SAFETY: The `__pinned_init` function is implemented such that it
958958
// - returns `Ok(())` on successful initialization,
@@ -1055,12 +1055,12 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> {
10551055
where
10561056
F: FnOnce(&mut T) -> Result<(), E>,
10571057
{
1058-
ChainInit(self, f, PhantomData)
1058+
ChainInit(self, f, __internal::PhantomInvariant::new())
10591059
}
10601060
}
10611061

10621062
/// An initializer returned by [`Init::chain`].
1063-
pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>);
1063+
pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::PhantomInvariant<(E, T)>);
10641064

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

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

11331133
/// Changes the to be initialized type.

tests/ui/expand/many_generics.expanded.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ const _: () = {
5555
where
5656
T: Bar<'a, 1>,
5757
{
58-
__phantom: ::core::marker::PhantomData<
59-
fn(Foo<'a, 'b, T, SIZE>) -> Foo<'a, 'b, T, SIZE>,
60-
>,
58+
__phantom: ::pin_init::__internal::PhantomInvariant<Foo<'a, 'b, T, SIZE>>,
6159
}
6260
impl<'a, 'b: 'a, T: Bar<'b> + ?Sized + 'a, const SIZE: usize> ::core::clone::Clone
6361
for __ThePinData<'a, 'b, T, SIZE>
@@ -161,7 +159,7 @@ const _: () = {
161159
type PinData = __ThePinData<'a, 'b, T, SIZE>;
162160
unsafe fn __pin_data() -> Self::PinData {
163161
__ThePinData {
164-
__phantom: ::core::marker::PhantomData,
162+
__phantom: ::pin_init::__internal::PhantomInvariant::new(),
165163
}
166164
}
167165
}
@@ -181,10 +179,8 @@ const _: () = {
181179
where
182180
T: Bar<'a, 1>,
183181
{
184-
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
185-
__phantom: ::core::marker::PhantomData<
186-
fn(Foo<'a, 'b, T, SIZE>) -> Foo<'a, 'b, T, SIZE>,
187-
>,
182+
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
183+
__phantom: ::pin_init::__internal::PhantomInvariant<Foo<'a, 'b, T, SIZE>>,
188184
_pin: PhantomPinned,
189185
}
190186
#[doc(hidden)]

tests/ui/expand/pin-data.expanded.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl Foo {
3535
const _: () = {
3636
#[doc(hidden)]
3737
struct __ThePinData {
38-
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
38+
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
3939
}
4040
impl ::core::clone::Clone for __ThePinData {
4141
fn clone(&self) -> Self {
@@ -94,7 +94,7 @@ const _: () = {
9494
type PinData = __ThePinData;
9595
unsafe fn __pin_data() -> Self::PinData {
9696
__ThePinData {
97-
__phantom: ::core::marker::PhantomData,
97+
__phantom: ::pin_init::__internal::PhantomInvariant::new(),
9898
}
9999
}
100100
}
@@ -103,8 +103,8 @@ const _: () = {
103103
}
104104
#[allow(dead_code)]
105105
struct __Unpin<'__pin> {
106-
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
107-
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
106+
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
107+
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
108108
_pin: PhantomPinned,
109109
}
110110
#[doc(hidden)]

tests/ui/expand/pinned_drop.expanded.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl Foo {
3535
const _: () = {
3636
#[doc(hidden)]
3737
struct __ThePinData {
38-
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
38+
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
3939
}
4040
impl ::core::clone::Clone for __ThePinData {
4141
fn clone(&self) -> Self {
@@ -94,7 +94,7 @@ const _: () = {
9494
type PinData = __ThePinData;
9595
unsafe fn __pin_data() -> Self::PinData {
9696
__ThePinData {
97-
__phantom: ::core::marker::PhantomData,
97+
__phantom: ::pin_init::__internal::PhantomInvariant::new(),
9898
}
9999
}
100100
}
@@ -103,8 +103,8 @@ const _: () = {
103103
}
104104
#[allow(dead_code)]
105105
struct __Unpin<'__pin> {
106-
__phantom_pin: ::core::marker::PhantomData<fn(&'__pin ()) -> &'__pin ()>,
107-
__phantom: ::core::marker::PhantomData<fn(Foo) -> Foo>,
106+
__phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
107+
__phantom: ::pin_init::__internal::PhantomInvariant<Foo>,
108108
_pin: PhantomPinned,
109109
}
110110
#[doc(hidden)]

0 commit comments

Comments
 (0)