• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

facet-rs / facet / 15239697956

25 May 2025 04:10PM UTC coverage: 57.866% (+0.1%) from 57.737%
15239697956

push

github

fasterthanlime
Fix documentation links

10078 of 17416 relevant lines covered (57.87%)

140.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.27
/facet-core/src/impls_core/pointer.rs
1
use core::{fmt, hash::Hash, mem::transmute};
2

3
use crate::{
4
    CmpFn, CmpFnTyped, DebugFn, DebugFnTyped, DisplayFn, DisplayFnTyped, Facet, HashFn,
5
    HashFnTyped, HasherProxy, MarkerTraits, PartialEqFn, PartialEqFnTyped, PartialOrdFn,
6
    PartialOrdFnTyped, PointerType, Shape, Type, TypeParam, ValuePointerType, ValueVTable,
7
};
8

9
macro_rules! impl_facet_for_pointer {
10
    ($variant:ident: $type:ty => $shape:expr => $vtable_builder:expr => $ptr_type:ident, $mutable:expr) => {
11
        unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for $type {
12
            const VTABLE: &'static ValueVTable = &const {
13
                $vtable_builder
14
                    .type_name(|f, opts| {
69✔
15
                        if let Some(opts) = opts.for_children() {
69✔
16
                            if stringify!($ptr_type) == "Raw" {
69✔
17
                                if $mutable {
18
                                    write!(f, "*mut ")?;
6✔
19
                                } else {
20
                                    write!(f, "*const ")?;
14✔
21
                                }
22
                            } else {
23
                                write!(f, "&")?;
49✔
24
                                if $mutable {
25
                                    write!(f, "mut ")?;
10✔
26
                                }
39✔
27
                            }
28
                            (T::VTABLE.type_name)(f, opts)
69✔
29
                        } else {
30
                            if stringify!($ptr_type) == "Raw" {
×
31
                                if $mutable {
32
                                    write!(f, "*mut ⋯")
×
33
                                } else {
34
                                    write!(f, "*const ⋯")
×
35
                                }
36
                            } else {
37
                                write!(f, "&")?;
×
38
                                if $mutable {
39
                                    write!(f, "mut ⋯")
×
40
                                } else {
41
                                    write!(f, "⋯")
×
42
                                }
43
                            }
44
                        }
45
                    })
69✔
46
                    .build()
47
            };
48

49
            const SHAPE: &'static Shape<'static> = &const {
50
                $shape
51
                    .type_identifier(
52
                        const {
53
                            let ptr_type = stringify!($ptr_type);
54
                            let is_raw = ptr_type.len() == 3
55
                                && ptr_type.as_bytes()[0] == b'R'
56
                                && ptr_type.as_bytes()[1] == b'a'
57
                                && ptr_type.as_bytes()[2] == b'w';
58
                            if is_raw {
59
                                if $mutable { "*mut _" } else { "*const _" }
60
                            } else {
61
                                if $mutable { "&mut _" } else { "&_" }
62
                            }
63
                        },
64
                    )
65
                    .type_params(&[TypeParam {
66
                        name: "T",
67
                        shape: || T::SHAPE,
68
                    }])
69
                    .ty({
70
                        let is_wide =
71
                            ::core::mem::size_of::<$type>() != ::core::mem::size_of::<*const ()>();
72
                        let vpt = ValuePointerType {
73
                            mutable: $mutable,
74
                            wide: is_wide,
75
                            target: || T::SHAPE,
76
                        };
77

78
                        Type::Pointer(PointerType::$ptr_type(vpt))
79
                    })
80
                    .build()
81
            };
82
        }
83
    };
84
}
85

86
// *const pointers
87
impl_facet_for_pointer!(
88
    Raw: *const T
89
        => Shape::builder_for_sized::<Self>()
90
            .inner(|| T::SHAPE)
91
        => ValueVTable::builder::<Self>()
92
            .marker_traits(|| {
18✔
93
                let mut marker_traits = MarkerTraits::EQ
18✔
94
                    .union(MarkerTraits::COPY)
18✔
95
                    .union(MarkerTraits::UNPIN);
18✔
96

97
                if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE) {
18✔
98
                    marker_traits = marker_traits.union(MarkerTraits::UNWIND_SAFE).union(MarkerTraits::REF_UNWIND_SAFE);
16✔
99
                }
16✔
100

101
                marker_traits
18✔
102
            })
18✔
103
            .debug(|| Some(fmt::Debug::fmt))
92✔
104
            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
2✔
105
            .eq(|| Some(|left, right| left.cast::<()>().eq(&right.cast::<()>())))
7✔
106
            .partial_ord(|| Some(|&left, &right| {
7✔
107
                left.cast::<()>().partial_cmp(&right.cast::<()>())
7✔
108
            }))
7✔
109
            .ord(|| Some(|&left, &right| left.cast::<()>().cmp(&right.cast::<()>())))
4✔
110
            .hash(|| Some(|value, hasher_this, hasher_write_fn| {
×
111
                value.hash(&mut unsafe {
×
112
                    HasherProxy::new(hasher_this, hasher_write_fn)
×
113
                })
×
114
            }))
×
115
        => Raw, false
116
);
117

118
// *mut pointers
119
impl_facet_for_pointer!(
120
    Raw: *mut T
121
        => Shape::builder_for_sized::<Self>()
122
            .inner(|| T::SHAPE)
123
        => ValueVTable::builder::<Self>()
124
            .marker_traits(|| {
4✔
125
                let mut marker_traits = MarkerTraits::EQ
4✔
126
                    .union(MarkerTraits::COPY)
4✔
127
                    .union(MarkerTraits::UNPIN);
4✔
128

129
                if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE) {
4✔
130
                    marker_traits = marker_traits.union(MarkerTraits::UNWIND_SAFE).union(MarkerTraits::REF_UNWIND_SAFE);
2✔
131
                }
2✔
132

133
                marker_traits
4✔
134
            })
4✔
135
            .debug(|| Some(fmt::Debug::fmt))
28✔
136
            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
2✔
137
            .eq(|| Some(|left, right| left.cast::<()>().eq(&right.cast::<()>())))
3✔
138
            .partial_ord(|| Some(|&left, &right| {
3✔
139
                left.cast::<()>().partial_cmp(&right.cast::<()>())
3✔
140
            }))
3✔
141
            .ord(|| Some(|&left, &right| left.cast::<()>().cmp(&right.cast::<()>())))
2✔
142
            .hash(|| Some(|value, hasher_this, hasher_write_fn| {
×
143
                value.hash(&mut unsafe {
×
144
                    HasherProxy::new(hasher_this, hasher_write_fn)
×
145
                })
×
146
            }))
×
147
        => Raw, true
148
);
149

150
// &T references
151
impl_facet_for_pointer!(
152
    Reference: &'a T
153
        => Shape::builder_for_sized::<Self>()
154
        => {
155
            ValueVTable::builder::<Self>()
156
                .marker_traits(|| {
22✔
157
                    let mut marker_traits = MarkerTraits::COPY.union(MarkerTraits::UNPIN);
22✔
158
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::EQ) {
22✔
159
                        marker_traits = marker_traits.union(MarkerTraits::EQ);
20✔
160
                    }
20✔
161
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SYNC) {
22✔
162
                        marker_traits = marker_traits.union(MarkerTraits::SEND).union(MarkerTraits::SYNC);
18✔
163
                    }
18✔
164
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE) {
22✔
165
                        marker_traits = marker_traits.union(MarkerTraits::UNWIND_SAFE).union(MarkerTraits::REF_UNWIND_SAFE);
20✔
166
                    }
20✔
167

168
                    marker_traits
22✔
169
                })
22✔
170
                .clone_into(|| Some(|src, dst| unsafe { dst.put(core::ptr::read(src)) }))
7✔
171
                .debug(|| {
212✔
172
                    if (T::VTABLE.debug)().is_some() {
212✔
173
                        Some(|value, f| {
130✔
174
                            let debug_fn = unsafe { transmute::<DebugFn, DebugFnTyped<T>>((T::VTABLE.debug)().unwrap()) };
130✔
175
                            debug_fn(*value, f)
130✔
176
                        })
130✔
177
                    } else {
178
                        None
×
179
                    }
180
                })
212✔
181
                .display(|| {
64✔
182
                    if (T::VTABLE.display)().is_some() {
64✔
183
                        Some(|value, f| {
26✔
184
                            let display_fn = unsafe { transmute::<DisplayFn, DisplayFnTyped<T>>((T::VTABLE.display)().unwrap()) };
26✔
185
                            display_fn(*value, f)
26✔
186
                        })
26✔
187
                    } else {
188
                        None
23✔
189
                    }
190
                })
64✔
191
                .eq(|| {
39✔
192
                    if (T::VTABLE.eq)().is_some() {
39✔
193
                        Some(|a, b| {
15✔
194
                            let eq_fn = unsafe { transmute::<PartialEqFn, PartialEqFnTyped<T>>((T::VTABLE.eq)().unwrap()) };
15✔
195
                            eq_fn(*a, *b)
15✔
196
                        })
15✔
197
                    } else {
198
                        None
2✔
199
                    }
200
                })
39✔
201
                .partial_ord(|| {
32✔
202
                    if (T::VTABLE.partial_ord)().is_some() {
32✔
203
                        Some(|a, b| {
15✔
204
                            let partial_ord_fn = unsafe { transmute::<PartialOrdFn, PartialOrdFnTyped<T>>((T::VTABLE.partial_ord)().unwrap()) };
15✔
205
                            partial_ord_fn(*a, *b)
15✔
206
                        })
15✔
207
                    } else {
208
                        None
2✔
209
                    }
210
                })
32✔
211
                .ord(|| {
29✔
212
                    if (T::VTABLE.ord)().is_some() {
29✔
213
                        Some(|a, b| {
8✔
214
                            let ord_fn = unsafe { transmute::<CmpFn, CmpFnTyped<T>>((T::VTABLE.ord)().unwrap()) };
8✔
215
                            ord_fn(*a, *b)
8✔
216
                        })
8✔
217
                    } else {
218
                        None
2✔
219
                    }
220
                })
29✔
221
                .hash(|| {
×
222
                    if (T::VTABLE.hash)().is_some() {
×
223
                        Some(|value, hasher_this, hasher_write_fn| {
×
224
                            let hash_fn = unsafe { transmute::<HashFn, HashFnTyped<T>>((T::VTABLE.hash)().unwrap()) };
×
225
                            hash_fn(*value, hasher_this, hasher_write_fn)
×
226
                        })
×
227
                    } else {
228
                        None
×
229
                    }
230
                })
×
231
        }
232
        => Reference, false
233
);
234

235
// &mut T references
236
impl_facet_for_pointer!(
237
    Reference: &'a mut T
238
        => Shape::builder_for_sized::<Self>()
239
        => {
240
            ValueVTable::builder::<Self>()
241
                .marker_traits(|| {
6✔
242
                    let mut marker_traits = MarkerTraits::UNPIN;
6✔
243
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::EQ) {
6✔
244
                        marker_traits = marker_traits.union(MarkerTraits::EQ);
4✔
245
                    }
4✔
246
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SEND) {
6✔
247
                        marker_traits = marker_traits.union(MarkerTraits::SEND);
2✔
248
                    }
4✔
249
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SYNC) {
6✔
250
                        marker_traits = marker_traits.union(MarkerTraits::SYNC);
2✔
251
                    }
4✔
252
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE) {
6✔
253
                        marker_traits = marker_traits.union(MarkerTraits::REF_UNWIND_SAFE);
4✔
254
                    }
4✔
255

256
                    marker_traits
6✔
257
                })
6✔
258
                .debug(|| {
40✔
259
                    if (T::VTABLE.debug)().is_some() {
40✔
260
                        Some(|value, f| {
30✔
261
                            let debug_fn = unsafe { transmute::<DebugFn, DebugFnTyped<T>>((T::VTABLE.debug)().unwrap()) };
30✔
262
                            debug_fn(*value, f)
30✔
263
                        })
30✔
264
                    } else {
265
                        None
×
266
                    }
267
                })
40✔
268
                .display(|| {
18✔
269
                    if (T::VTABLE.display)().is_some() {
18✔
270
                        Some(|value, f| {
6✔
271
                            let display_fn = unsafe { transmute::<DisplayFn, DisplayFnTyped<T>>((T::VTABLE.display)().unwrap()) };
6✔
272
                            display_fn(*value, f)
6✔
273
                        })
6✔
274
                    } else {
275
                        None
10✔
276
                    }
277
                })
18✔
278
                .eq(|| {
10✔
279
                    if (T::VTABLE.eq)().is_some() {
10✔
280
                        Some(|a, b| {
4✔
281
                            let eq_fn = unsafe { transmute::<PartialEqFn, PartialEqFnTyped<T>>((T::VTABLE.eq)().unwrap()) };
4✔
282
                            eq_fn(*a, *b)
4✔
283
                        })
4✔
284
                    } else {
285
                        None
2✔
286
                    }
287
                })
10✔
288
                .partial_ord(|| {
8✔
289
                    if (T::VTABLE.partial_ord)().is_some() {
8✔
290
                        Some(|a, b| {
4✔
291
                            let partial_ord_fn = unsafe { transmute::<PartialOrdFn, PartialOrdFnTyped<T>>((T::VTABLE.partial_ord)().unwrap()) };
4✔
292
                            partial_ord_fn(*a, *b)
4✔
293
                        })
4✔
294
                    } else {
295
                        None
2✔
296
                    }
297
                })
8✔
298
                .ord(|| {
8✔
299
                    if (T::VTABLE.ord)().is_some() {
8✔
300
                        Some(|a, b| {
2✔
301
                            let ord_fn = unsafe { transmute::<CmpFn, CmpFnTyped<T>>((T::VTABLE.ord)().unwrap()) };
2✔
302
                            ord_fn(*a, *b)
2✔
303
                        })
2✔
304
                    } else {
305
                        None
2✔
306
                    }
307
                })
8✔
308
                .hash(|| {
×
309
                    if (T::VTABLE.hash)().is_some() {
×
310
                        Some(|value, hasher_this, hasher_write_fn| {
×
311
                            let hash_fn = unsafe { transmute::<HashFn, HashFnTyped<T>>((T::VTABLE.hash)().unwrap()) };
×
312
                            hash_fn(*value, hasher_this, hasher_write_fn)
×
313
                        })
×
314
                    } else {
315
                        None
×
316
                    }
317
                })
×
318
        }
319
        => Reference, true
320
);
321

322
#[cfg(test)]
323
mod test {
324
    use core::panic::{RefUnwindSafe, UnwindSafe};
325
    use impls::impls;
326

327
    #[allow(unused)]
328
    const fn assert_impls_unwind_safe<T: UnwindSafe>() {}
×
329
    #[allow(unused)]
330
    const fn assert_impls_ref_unwind_safe<T: RefUnwindSafe>() {}
×
331

332
    #[allow(unused)]
333
    const fn ref_unwind_safe<T: RefUnwindSafe>() {
×
334
        assert_impls_unwind_safe::<&T>();
×
335
        assert_impls_ref_unwind_safe::<&T>();
×
336

337
        assert_impls_ref_unwind_safe::<&mut T>();
×
338

339
        assert_impls_unwind_safe::<*const T>();
×
340
        assert_impls_ref_unwind_safe::<*const T>();
×
341

342
        assert_impls_unwind_safe::<*mut T>();
×
343
        assert_impls_ref_unwind_safe::<*mut T>();
×
344
    }
×
345

346
    #[test]
347
    fn mut_ref_not_unwind_safe() {
1✔
348
        assert!(impls!(&mut (): !UnwindSafe));
1✔
349
    }
1✔
350
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc