facet_core/impls_core/
pointer.rs

1use core::fmt;
2
3use crate::{
4    Facet, MarkerTraits, PointerType, Shape, Type, TypeParam, ValuePointerType, ValueVTable,
5};
6
7// *const pointers
8unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for *const T {
9    const VTABLE: &'static ValueVTable = &const {
10        ValueVTable::builder::<Self>()
11            .marker_traits(|| {
12                let mut marker_traits = MarkerTraits::EQ
13                    .union(MarkerTraits::COPY)
14                    .union(MarkerTraits::UNPIN);
15
16                if T::SHAPE
17                    .vtable
18                    .marker_traits()
19                    .contains(MarkerTraits::REF_UNWIND_SAFE)
20                {
21                    marker_traits = marker_traits
22                        .union(MarkerTraits::UNWIND_SAFE)
23                        .union(MarkerTraits::REF_UNWIND_SAFE);
24                }
25
26                marker_traits
27            })
28            .debug(|| Some(fmt::Debug::fmt))
29            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
30            .type_name(|f, opts| {
31                if let Some(opts) = opts.for_children() {
32                    write!(f, "*const ")?;
33                    (T::VTABLE.type_name())(f, opts)
34                } else {
35                    write!(f, "*const ⋯")
36                }
37            })
38            .build()
39    };
40
41    const SHAPE: &'static Shape = &const {
42        Shape::builder_for_sized::<Self>()
43            .inner(|| T::SHAPE)
44            .type_identifier("*const _")
45            .type_params(&[TypeParam {
46                name: "T",
47                shape: || T::SHAPE,
48            }])
49            .ty({
50                let is_wide = ::core::mem::size_of::<Self>() != ::core::mem::size_of::<*const ()>();
51                let vpt = ValuePointerType {
52                    mutable: false,
53                    wide: is_wide,
54                    target: || T::SHAPE,
55                };
56
57                Type::Pointer(PointerType::Raw(vpt))
58            })
59            .build()
60    };
61}
62
63// *mut pointers
64unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for *mut T {
65    const VTABLE: &'static ValueVTable = &const {
66        ValueVTable::builder::<Self>()
67            .marker_traits(|| {
68                let mut marker_traits = MarkerTraits::EQ
69                    .union(MarkerTraits::COPY)
70                    .union(MarkerTraits::UNPIN);
71
72                if T::SHAPE
73                    .vtable
74                    .marker_traits()
75                    .contains(MarkerTraits::REF_UNWIND_SAFE)
76                {
77                    marker_traits = marker_traits
78                        .union(MarkerTraits::UNWIND_SAFE)
79                        .union(MarkerTraits::REF_UNWIND_SAFE);
80                }
81
82                marker_traits
83            })
84            .debug(|| Some(fmt::Debug::fmt))
85            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
86            .type_name(|f, opts| {
87                if let Some(opts) = opts.for_children() {
88                    write!(f, "*mut ")?;
89                    (T::VTABLE.type_name())(f, opts)
90                } else {
91                    write!(f, "*mut ⋯")
92                }
93            })
94            .build()
95    };
96
97    const SHAPE: &'static Shape = &const {
98        Shape::builder_for_sized::<Self>()
99            .inner(|| T::SHAPE)
100            .type_identifier("*mut _")
101            .type_params(&[TypeParam {
102                name: "T",
103                shape: || T::SHAPE,
104            }])
105            .ty({
106                let is_wide = ::core::mem::size_of::<Self>() != ::core::mem::size_of::<*const ()>();
107                let vpt = ValuePointerType {
108                    mutable: true,
109                    wide: is_wide,
110                    target: || T::SHAPE,
111                };
112
113                Type::Pointer(PointerType::Raw(vpt))
114            })
115            .build()
116    };
117}
118
119#[cfg(test)]
120mod test {
121    use core::panic::{RefUnwindSafe, UnwindSafe};
122    use impls::impls;
123
124    #[allow(unused)]
125    const fn assert_impls_unwind_safe<T: UnwindSafe>() {}
126    #[allow(unused)]
127    const fn assert_impls_ref_unwind_safe<T: RefUnwindSafe>() {}
128
129    #[allow(unused)]
130    const fn ref_unwind_safe<T: RefUnwindSafe>() {
131        assert_impls_unwind_safe::<&T>();
132        assert_impls_ref_unwind_safe::<&T>();
133
134        assert_impls_ref_unwind_safe::<&mut T>();
135
136        assert_impls_unwind_safe::<*const T>();
137        assert_impls_ref_unwind_safe::<*const T>();
138
139        assert_impls_unwind_safe::<*mut T>();
140        assert_impls_ref_unwind_safe::<*mut T>();
141    }
142
143    #[test]
144    fn mut_ref_not_unwind_safe() {
145        assert!(impls!(&mut (): !UnwindSafe));
146    }
147}