Skip to main content

facet_core/impls/core/
phantom.rs

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