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 builder = ValueVTable::builder::<Self>()
129 .marker_traits(
130 MarkerTraits::UNPIN
131 .union(MarkerTraits::COPY)
132 )
133 .clone_into(|src, dst| unsafe { dst.put(core::ptr::read(src)) });
134
135 if T::VTABLE.debug.is_some() {
137 builder = builder.debug(|value, f| {
138 let target_ptr = crate::PtrConst::new(value);
139 unsafe { (T::VTABLE.debug.unwrap())(target_ptr, f) }
140 });
141 }
142
143 if T::VTABLE.display.is_some() {
144 builder = builder.display(|value, f| {
145 let target_ptr = crate::PtrConst::new(value);
146 unsafe { (T::VTABLE.display.unwrap())(target_ptr, f) }
147 });
148 }
149
150 if T::VTABLE.eq.is_some() {
151 builder = builder.eq(|a, b| {
152 let a_ptr = crate::PtrConst::new(a);
153 let b_ptr = crate::PtrConst::new(b);
154 unsafe { (T::VTABLE.eq.unwrap())(a_ptr, b_ptr) }
155 });
156 }
157
158 if T::VTABLE.partial_ord.is_some() {
159 builder = builder.partial_ord(|a, b| {
160 let a_ptr = crate::PtrConst::new(a);
161 let b_ptr = crate::PtrConst::new(b);
162 unsafe { (T::VTABLE.partial_ord.unwrap())(a_ptr, b_ptr) }
163 });
164 }
165
166 if T::VTABLE.ord.is_some() {
167 builder = builder.ord(|a, b| {
168 let a_ptr = crate::PtrConst::new(a);
169 let b_ptr = crate::PtrConst::new(b);
170 unsafe { (T::VTABLE.ord.unwrap())(a_ptr, b_ptr) }
171 });
172 }
173
174 if T::VTABLE.hash.is_some() {
175 builder = builder.hash(|value, hasher_this, hasher_write_fn| {
176 let target_ptr = crate::PtrConst::new(value);
177 unsafe { (T::VTABLE.hash.unwrap())(target_ptr, hasher_this, hasher_write_fn) }
178 });
179 }
180
181 builder
182 }
183 => Reference, false
184);
185
186impl_facet_for_pointer!(
188 Reference: &'a mut T
189 => Shape::builder_for_sized::<Self>()
190 => {
191 let mut builder = ValueVTable::builder::<Self>()
192 .marker_traits(
193 MarkerTraits::UNPIN
194 );
195
196 if T::VTABLE.debug.is_some() {
198 builder = builder.debug(|value, f| {
199 let target_ptr = crate::PtrConst::new(value);
200 unsafe { (T::VTABLE.debug.unwrap())(target_ptr, f) }
201 });
202 }
203
204 if T::VTABLE.display.is_some() {
205 builder = builder.display(|value, f| {
206 let target_ptr = crate::PtrConst::new(value);
207 unsafe { (T::VTABLE.display.unwrap())(target_ptr, f) }
208 });
209 }
210
211 if T::VTABLE.eq.is_some() {
212 builder = builder.eq(|a, b| {
213 let a_ptr = crate::PtrConst::new(a);
214 let b_ptr = crate::PtrConst::new(b);
215 unsafe { (T::VTABLE.eq.unwrap())(a_ptr, b_ptr) }
216 });
217 }
218
219 if T::VTABLE.partial_ord.is_some() {
220 builder = builder.partial_ord(|a, b| {
221 let a_ptr = crate::PtrConst::new(a);
222 let b_ptr = crate::PtrConst::new(b);
223 unsafe { (T::VTABLE.partial_ord.unwrap())(a_ptr, b_ptr) }
224 });
225 }
226
227 if T::VTABLE.ord.is_some() {
228 builder = builder.ord(|a, b| {
229 let a_ptr = crate::PtrConst::new(a);
230 let b_ptr = crate::PtrConst::new(b);
231 unsafe { (T::VTABLE.ord.unwrap())(a_ptr, b_ptr) }
232 });
233 }
234
235 if T::VTABLE.hash.is_some() {
236 builder = builder.hash(|value, hasher_this, hasher_write_fn| {
237 let target_ptr = crate::PtrConst::new(value);
238 unsafe { (T::VTABLE.hash.unwrap())(target_ptr, hasher_this, hasher_write_fn) }
239 });
240 }
241
242 builder
243 }
244 => Reference, true
245);