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