facet_core/impls_core/
pointer.rs1use core::{fmt, hash::Hash};
2
3use crate::{
4 Facet, HasherProxy, MarkerTraits, PointerType, Shape, Type, TypeParam, ValuePointerType,
5 ValueVTable,
6};
7
8macro_rules! impl_facet_for_pointer {
9 ($variant:ident: $type:ty => $shape:expr => $vtable_builder:expr => $ptr_type:ident, $mutable:expr) => {
10 unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for $type {
11 const VTABLE: &'static ValueVTable = &const {
12 $vtable_builder
13 .type_name(|f, opts| {
14 if let Some(opts) = opts.for_children() {
15 if stringify!($ptr_type) == "Raw" {
16 if $mutable {
17 write!(f, "*mut ")?;
18 } else {
19 write!(f, "*const ")?;
20 }
21 } else {
22 write!(f, "&")?;
23 if $mutable {
24 write!(f, "mut ")?;
25 }
26 }
27 (T::VTABLE.type_name)(f, opts)
28 } else {
29 if stringify!($ptr_type) == "Raw" {
30 if $mutable {
31 write!(f, "*mut ⋯")
32 } else {
33 write!(f, "*const ⋯")
34 }
35 } else {
36 write!(f, "&")?;
37 if $mutable {
38 write!(f, "mut ⋯")
39 } else {
40 write!(f, "⋯")
41 }
42 }
43 }
44 })
45 .build()
46 };
47
48 const SHAPE: &'static Shape<'static> = &const {
49 $shape
50 .type_params(&[TypeParam {
51 name: "T",
52 shape: || T::SHAPE,
53 }])
54 .ty({
55 let is_wide =
56 ::core::mem::size_of::<$type>() != ::core::mem::size_of::<*const ()>();
57 let vpt = ValuePointerType {
58 mutable: $mutable,
59 wide: is_wide,
60 target: || T::SHAPE,
61 };
62
63 Type::Pointer(PointerType::$ptr_type(vpt))
64 })
65 .build()
66 };
67 }
68 };
69}
70
71impl_facet_for_pointer!(
73 Raw: *const T
74 => Shape::builder_for_sized::<Self>()
75 .inner(|| T::SHAPE)
76 => ValueVTable::builder::<Self>()
77 .marker_traits(
78 MarkerTraits::EQ
79 .union(MarkerTraits::COPY)
80 .union(MarkerTraits::UNPIN),
81 )
82 .debug(fmt::Debug::fmt)
83 .clone_into(|src, dst| unsafe { dst.put(*src) })
84 .eq(|left, right| left.cast::<()>().eq(&right.cast::<()>()))
85 .partial_ord(|&left, &right| {
86 left.cast::<()>().partial_cmp(&right.cast::<()>())
87 })
88 .ord(|&left, &right| left.cast::<()>().cmp(&right.cast::<()>()))
89 .hash(|value, hasher_this, hasher_write_fn| {
90 value.hash(&mut unsafe {
91 HasherProxy::new(hasher_this, hasher_write_fn)
92 })
93 })
94 => Raw, false
95);
96
97impl_facet_for_pointer!(
99 Raw: *mut T
100 => Shape::builder_for_sized::<Self>()
101 .inner(|| T::SHAPE)
102 => ValueVTable::builder::<Self>()
103 .marker_traits(
104 MarkerTraits::EQ
105 .union(MarkerTraits::COPY)
106 .union(MarkerTraits::UNPIN),
107 )
108 .debug(fmt::Debug::fmt)
109 .clone_into(|src, dst| unsafe { dst.put(*src) })
110 .eq(|left, right| left.cast::<()>().eq(&right.cast::<()>()))
111 .partial_ord(|&left, &right| {
112 left.cast::<()>().partial_cmp(&right.cast::<()>())
113 })
114 .ord(|&left, &right| left.cast::<()>().cmp(&right.cast::<()>()))
115 .hash(|value, hasher_this, hasher_write_fn| {
116 value.hash(&mut unsafe {
117 HasherProxy::new(hasher_this, hasher_write_fn)
118 })
119 })
120 => Raw, true
121);
122
123impl_facet_for_pointer!(
125 Reference: &'a T
126 => Shape::builder_for_sized::<Self>()
127 => {
128 let mut marker_traits = MarkerTraits::COPY.union(MarkerTraits::UNPIN);
129 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::EQ) {
130 marker_traits = marker_traits.union(MarkerTraits::EQ);
131 }
132 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SYNC) {
133 marker_traits = marker_traits.union(MarkerTraits::SEND).union(MarkerTraits::SYNC);
134 }
135
136 let mut builder = ValueVTable::builder::<Self>()
137 .marker_traits(marker_traits)
138 .clone_into(|src, dst| unsafe { dst.put(core::ptr::read(src)) });
139
140 if T::VTABLE.debug.is_some() {
142 builder = builder.debug(|value, f| {
143 let target_ptr = crate::PtrConst::new(value);
144 unsafe { (T::VTABLE.debug.unwrap())(target_ptr, f) }
145 });
146 }
147
148 if T::VTABLE.display.is_some() {
149 builder = builder.display(|value, f| {
150 let target_ptr = crate::PtrConst::new(value);
151 unsafe { (T::VTABLE.display.unwrap())(target_ptr, f) }
152 });
153 }
154
155 if T::VTABLE.eq.is_some() {
156 builder = builder.eq(|a, b| {
157 let a_ptr = crate::PtrConst::new(a);
158 let b_ptr = crate::PtrConst::new(b);
159 unsafe { (T::VTABLE.eq.unwrap())(a_ptr, b_ptr) }
160 });
161 }
162
163 if T::VTABLE.partial_ord.is_some() {
164 builder = builder.partial_ord(|a, b| {
165 let a_ptr = crate::PtrConst::new(a);
166 let b_ptr = crate::PtrConst::new(b);
167 unsafe { (T::VTABLE.partial_ord.unwrap())(a_ptr, b_ptr) }
168 });
169 }
170
171 if T::VTABLE.ord.is_some() {
172 builder = builder.ord(|a, b| {
173 let a_ptr = crate::PtrConst::new(a);
174 let b_ptr = crate::PtrConst::new(b);
175 unsafe { (T::VTABLE.ord.unwrap())(a_ptr, b_ptr) }
176 });
177 }
178
179 if T::VTABLE.hash.is_some() {
180 builder = builder.hash(|value, hasher_this, hasher_write_fn| {
181 let target_ptr = crate::PtrConst::new(value);
182 unsafe { (T::VTABLE.hash.unwrap())(target_ptr, hasher_this, hasher_write_fn) }
183 });
184 }
185
186 builder
187 }
188 => Reference, false
189);
190
191impl_facet_for_pointer!(
193 Reference: &'a mut T
194 => Shape::builder_for_sized::<Self>()
195 => {
196 let mut marker_traits = MarkerTraits::UNPIN;
197 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::EQ) {
198 marker_traits = marker_traits.union(MarkerTraits::EQ);
199 }
200 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SEND) {
201 marker_traits = marker_traits.union(MarkerTraits::SEND);
202 }
203 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SYNC) {
204 marker_traits = marker_traits.union(MarkerTraits::SYNC);
205 }
206
207 let mut builder = ValueVTable::builder::<Self>()
208 .marker_traits(marker_traits);
209
210 if T::VTABLE.debug.is_some() {
212 builder = builder.debug(|value, f| {
213 let target_ptr = crate::PtrConst::new(value);
214 unsafe { (T::VTABLE.debug.unwrap())(target_ptr, f) }
215 });
216 }
217
218 if T::VTABLE.display.is_some() {
219 builder = builder.display(|value, f| {
220 let target_ptr = crate::PtrConst::new(value);
221 unsafe { (T::VTABLE.display.unwrap())(target_ptr, f) }
222 });
223 }
224
225 if T::VTABLE.eq.is_some() {
226 builder = builder.eq(|a, b| {
227 let a_ptr = crate::PtrConst::new(a);
228 let b_ptr = crate::PtrConst::new(b);
229 unsafe { (T::VTABLE.eq.unwrap())(a_ptr, b_ptr) }
230 });
231 }
232
233 if T::VTABLE.partial_ord.is_some() {
234 builder = builder.partial_ord(|a, b| {
235 let a_ptr = crate::PtrConst::new(a);
236 let b_ptr = crate::PtrConst::new(b);
237 unsafe { (T::VTABLE.partial_ord.unwrap())(a_ptr, b_ptr) }
238 });
239 }
240
241 if T::VTABLE.ord.is_some() {
242 builder = builder.ord(|a, b| {
243 let a_ptr = crate::PtrConst::new(a);
244 let b_ptr = crate::PtrConst::new(b);
245 unsafe { (T::VTABLE.ord.unwrap())(a_ptr, b_ptr) }
246 });
247 }
248
249 if T::VTABLE.hash.is_some() {
250 builder = builder.hash(|value, hasher_this, hasher_write_fn| {
251 let target_ptr = crate::PtrConst::new(value);
252 unsafe { (T::VTABLE.hash.unwrap())(target_ptr, hasher_this, hasher_write_fn) }
253 });
254 }
255
256 builder
257 }
258 => Reference, true
259);