facet_core/impls/core/
phantom.rs

1use crate::{
2    Def, Facet, HashProxy, OxPtrConst, OxPtrMut, Repr, Shape, ShapeBuilder, StructKind, StructType,
3    Type, TypeOpsIndirect, UserType, VTableIndirect,
4};
5
6unsafe fn phantom_drop(_ptr: OxPtrMut) {
7    // PhantomData is zero-sized, nothing to drop
8}
9
10unsafe fn phantom_default(_dst: OxPtrMut) {
11    // PhantomData is zero-sized, nothing to write
12}
13
14// Shared vtable for all PhantomData<T> - the implementations don't depend on T
15const PHANTOM_VTABLE: VTableIndirect = VTableIndirect {
16    display: None,
17    debug: Some(phantom_debug),
18    hash: Some(phantom_hash),
19    invariants: None,
20    parse: None,
21    parse_bytes: None,
22    try_from: None,
23    try_into_inner: None,
24    try_borrow_inner: None,
25    partial_eq: Some(phantom_partial_eq),
26    partial_cmp: Some(phantom_partial_cmp),
27    cmp: Some(phantom_cmp),
28};
29
30// Type operations for all PhantomData<T>
31static PHANTOM_TYPE_OPS: TypeOpsIndirect = TypeOpsIndirect {
32    drop_in_place: phantom_drop,
33    default_in_place: Some(phantom_default),
34    clone_into: None,
35    is_truthy: None,
36};
37
38unsafe fn phantom_debug(
39    _ox: OxPtrConst,
40    f: &mut core::fmt::Formatter<'_>,
41) -> Option<core::fmt::Result> {
42    Some(f.write_str("PhantomData"))
43}
44
45unsafe fn phantom_hash(_ox: OxPtrConst, _hasher: &mut HashProxy<'_>) -> Option<()> {
46    // PhantomData hashes to nothing
47    Some(())
48}
49
50unsafe fn phantom_partial_eq(_a: OxPtrConst, _b: OxPtrConst) -> Option<bool> {
51    // All PhantomData are equal
52    Some(true)
53}
54
55unsafe fn phantom_partial_cmp(
56    _a: OxPtrConst,
57    _b: OxPtrConst,
58) -> Option<Option<core::cmp::Ordering>> {
59    Some(Some(core::cmp::Ordering::Equal))
60}
61
62unsafe fn phantom_cmp(_a: OxPtrConst, _b: OxPtrConst) -> Option<core::cmp::Ordering> {
63    Some(core::cmp::Ordering::Equal)
64}
65
66unsafe impl<'a, T: ?Sized + 'a> Facet<'a> for core::marker::PhantomData<T> {
67    const SHAPE: &'static Shape = &const {
68        // PhantomData<T> implements Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash
69        // unconditionally (not depending on T) - but NOT Display
70
71        ShapeBuilder::for_sized::<core::marker::PhantomData<T>>("PhantomData")
72            .ty(Type::User(UserType::Struct(StructType {
73                repr: Repr::default(),
74                kind: StructKind::Unit,
75                fields: &[],
76            })))
77            .def(Def::Scalar)
78            .vtable_indirect(&PHANTOM_VTABLE)
79            .type_ops_indirect(&PHANTOM_TYPE_OPS)
80            .eq()
81            .copy()
82            .send()
83            .sync()
84            .build()
85    };
86}