1#![unstable(feature = "phantom_variance_markers", issue = "135806")]
2
3use super::PhantomData;
4use crate::any::type_name;
5use crate::clone::TrivialClone;
6use crate::cmp::Ordering;
7use crate::fmt;
8use crate::hash::{Hash, Hasher};
9
10macro_rules! first_token {
11 ($first:tt $($rest:tt)*) => {
12 $first
13 };
14}
15
16macro_rules! phantom_type {
17 ($(
18 $(#[$attr:meta])*
19 pub struct $name:ident <$t:ident> ($($inner:tt)*);
20 )*) => {$(
21 $(#[$attr])*
22 pub struct $name<$t>($($inner)*) where $t: ?Sized;
23
24 impl<T> $name<T>
25 where T: ?Sized
26 {
27 pub const fn new() -> Self {
29 Self(PhantomData)
30 }
31 }
32
33 impl<T> self::sealed::Sealed for $name<T> where T: ?Sized {
34 const VALUE: Self = Self::new();
35 }
36 impl<T> Variance for $name<T> where T: ?Sized {}
37
38 impl<T> Default for $name<T>
39 where T: ?Sized
40 {
41 fn default() -> Self {
42 Self(PhantomData)
43 }
44 }
45
46 impl<T> fmt::Debug for $name<T>
47 where T: ?Sized
48 {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 write!(f, "{}<{}>", stringify!($name), type_name::<T>())
51 }
52 }
53
54 impl<T> Clone for $name<T>
55 where T: ?Sized
56 {
57 fn clone(&self) -> Self {
58 *self
59 }
60 }
61
62 impl<T> Copy for $name<T> where T: ?Sized {}
63
64 #[doc(hidden)]
65 unsafe impl<T> TrivialClone for $name<T> where T: ?Sized {}
66
67 impl<T> PartialEq for $name<T>
68 where T: ?Sized
69 {
70 fn eq(&self, _: &Self) -> bool {
71 true
72 }
73 }
74
75 impl<T> Eq for $name<T> where T: ?Sized {}
76
77 impl<T> PartialOrd for $name<T>
78 where T: ?Sized
79 {
80 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
81 Some(Ordering::Equal)
82 }
83 }
84
85 impl<T> Ord for $name<T>
86 where T: ?Sized
87 {
88 fn cmp(&self, _: &Self) -> Ordering {
89 Ordering::Equal
90 }
91 }
92
93 impl<T> Hash for $name<T>
94 where T: ?Sized
95 {
96 fn hash<H: Hasher>(&self, _: &mut H) {}
97 }
98 )*};
99}
100
101macro_rules! phantom_lifetime {
102 ($(
103 $(#[$attr:meta])*
104 pub struct $name:ident <$lt:lifetime> ($($inner:tt)*);
105 )*) => {$(
106 $(#[$attr])*
107 #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
108 pub struct $name<$lt>($($inner)*);
109
110 impl $name<'_> {
111 pub const fn new() -> Self {
113 Self(first_token!($($inner)*)(PhantomData))
114 }
115 }
116
117 impl self::sealed::Sealed for $name<'_> {
118 const VALUE: Self = Self::new();
119 }
120 impl Variance for $name<'_> {}
121
122 impl fmt::Debug for $name<'_> {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 write!(f, "{}", stringify!($name))
125 }
126 }
127 )*};
128}
129
130#[automatically_derived]
impl<'a> crate::default::Default for PhantomInvariantLifetime<'a> {
#[inline]
fn default() -> PhantomInvariantLifetime<'a> {
PhantomInvariantLifetime(crate::default::Default::default())
}
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl<'a> crate::clone::TrivialClone for PhantomInvariantLifetime<'a> {
}
#[automatically_derived]
impl<'a> crate::clone::Clone for PhantomInvariantLifetime<'a> {
#[inline]
fn clone(&self) -> PhantomInvariantLifetime<'a> {
let _: crate::clone::AssertParamIsClone<PhantomInvariant<&'a ()>>;
*self
}
}
#[automatically_derived]
impl<'a> crate::marker::Copy for PhantomInvariantLifetime<'a> { }
#[automatically_derived]
impl<'a> crate::marker::StructuralPartialEq for PhantomInvariantLifetime<'a> {
}
#[automatically_derived]
impl<'a> crate::cmp::PartialEq for PhantomInvariantLifetime<'a> {
#[inline]
fn eq(&self, other: &PhantomInvariantLifetime<'a>) -> bool {
self.0 == other.0
}
}
#[automatically_derived]
impl<'a> crate::cmp::Eq for PhantomInvariantLifetime<'a> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: crate::cmp::AssertParamIsEq<PhantomInvariant<&'a ()>>;
}
}
#[automatically_derived]
impl<'a> crate::cmp::PartialOrd for PhantomInvariantLifetime<'a> {
#[inline]
fn partial_cmp(&self, other: &PhantomInvariantLifetime<'a>)
-> crate::option::Option<crate::cmp::Ordering> {
crate::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}
#[automatically_derived]
impl<'a> crate::cmp::Ord for PhantomInvariantLifetime<'a> {
#[inline]
fn cmp(&self, other: &PhantomInvariantLifetime<'a>)
-> crate::cmp::Ordering {
crate::cmp::Ord::cmp(&self.0, &other.0)
}
}
#[automatically_derived]
impl<'a> crate::hash::Hash for PhantomInvariantLifetime<'a> {
#[inline]
fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) {
crate::hash::Hash::hash(&self.0, state)
}
}
impl PhantomInvariantLifetime<'_> {
pub const fn new() -> Self { Self(PhantomInvariant(PhantomData)) }
}
impl self::sealed::Sealed for PhantomInvariantLifetime<'_> {
const VALUE: Self = Self::new();
}
impl Variance for PhantomInvariantLifetime<'_> {}
impl fmt::Debug for PhantomInvariantLifetime<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{0}", "PhantomInvariantLifetime"))
}
}phantom_lifetime! {
131 #[rustc_pub_transparent]
146 #[repr(transparent)]
147 pub struct PhantomCovariantLifetime<'a>(PhantomCovariant<&'a ()>);
148 #[rustc_pub_transparent]
163 #[repr(transparent)]
164 pub struct PhantomContravariantLifetime<'a>(PhantomContravariant<&'a ()>);
165 #[rustc_pub_transparent]
178 #[repr(transparent)]
179 pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>);
180}
181
182#[doc = r" Zero-sized type used to mark a type parameter as invariant."]
#[doc = r""]
#[doc =
r" Types that are both passed as an argument _and_ used as part of the return value from a"]
#[doc =
r" function are invariant. See [the reference][1] for more information."]
#[doc = r""]
#[doc =
r" [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance"]
#[doc = r""]
#[doc = r" ## Layout"]
#[doc = r""]
#[doc = r" For all `T`, the following are guaranteed:"]
#[doc = r" * `size_of::<PhantomInvariant<T>>() == 0`"]
#[doc = r" * `align_of::<PhantomInvariant<T>>() == 1`"]
#[rustc_pub_transparent]
#[repr(transparent)]
pub struct PhantomInvariant<T>(PhantomData<fn(T) -> T>) where T: ?Sized;
impl<T> PhantomInvariant<T> where T: ?Sized {
pub const fn new() -> Self { Self(PhantomData) }
}
impl<T> self::sealed::Sealed for PhantomInvariant<T> where T: ?Sized {
const VALUE: Self = Self::new();
}
impl<T> Variance for PhantomInvariant<T> where T: ?Sized {}
impl<T> Default for PhantomInvariant<T> where T: ?Sized {
fn default() -> Self { Self(PhantomData) }
}
impl<T> fmt::Debug for PhantomInvariant<T> where T: ?Sized {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{0}<{1}>", "PhantomInvariant",
type_name::<T>()))
}
}
impl<T> Clone for PhantomInvariant<T> where T: ?Sized {
fn clone(&self) -> Self { *self }
}
impl<T> Copy for PhantomInvariant<T> where T: ?Sized {}
#[doc(hidden)]
unsafe impl<T> TrivialClone for PhantomInvariant<T> where T: ?Sized { }
impl<T> PartialEq for PhantomInvariant<T> where T: ?Sized {
fn eq(&self, _: &Self) -> bool { true }
}
impl<T> Eq for PhantomInvariant<T> where T: ?Sized {}
impl<T> PartialOrd for PhantomInvariant<T> where T: ?Sized {
fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
Some(Ordering::Equal)
}
}
impl<T> Ord for PhantomInvariant<T> where T: ?Sized {
fn cmp(&self, _: &Self) -> Ordering { Ordering::Equal }
}
impl<T> Hash for PhantomInvariant<T> where T: ?Sized {
fn hash<H: Hasher>(&self, _: &mut H) {}
}phantom_type! {
183 #[rustc_pub_transparent]
199 #[repr(transparent)]
200 pub struct PhantomCovariant<T>(PhantomData<fn() -> T>);
201 #[rustc_pub_transparent]
217 #[repr(transparent)]
218 pub struct PhantomContravariant<T>(PhantomData<fn(T)>);
219 #[rustc_pub_transparent]
232 #[repr(transparent)]
233 pub struct PhantomInvariant<T>(PhantomData<fn(T) -> T>);
234}
235
236mod sealed {
237 pub trait Sealed {
238 const VALUE: Self;
239 }
240}
241
242pub trait Variance: sealed::Sealed + Default {}
244
245pub const fn variance<T>() -> T
280where
281 T: Variance,
282{
283 T::VALUE
284}