facet_core/impls_core/
pointer.rs1use core::fmt;
2
3use crate::{
4 Facet, MarkerTraits, PointerType, Shape, Type, TypeParam, ValuePointerType, ValueVTable,
5};
6
7unsafe 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
63unsafe 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}