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

facet-rs / facet / 15248533327

26 May 2025 07:15AM UTC coverage: 57.886% (+0.02%) from 57.866%
15248533327

push

github

fasterthanlime
Rename ValueVTable::eq to ValueVTable::partial_eq

Fixes #668

35 of 50 new or added lines in 16 files covered. (70.0%)

36 existing lines in 1 file now uncovered.

10086 of 17424 relevant lines covered (57.89%)

140.84 hits per line

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

77.72
/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| {
77✔
15
                        if let Some(opts) = opts.for_children() {
77✔
16
                            if stringify!($ptr_type) == "Raw" {
77✔
17
                                if $mutable {
18
                                    write!(f, "*mut ")?;
10✔
19
                                } else {
20
                                    write!(f, "*const ")?;
18✔
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)
77✔
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
                    })
77✔
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(|| {
22✔
93
                let mut marker_traits = MarkerTraits::EQ
22✔
94
                    .union(MarkerTraits::COPY)
22✔
95
                    .union(MarkerTraits::UNPIN);
22✔
96

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

101
                marker_traits
22✔
102
            })
22✔
103
            .debug(|| Some(fmt::Debug::fmt))
112✔
104
            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
4✔
105
            .partial_eq(|| Some(|&left, &right| core::ptr::eq(left, right)))
9✔
106
            .partial_ord(|| Some(|&left, &right| {
9✔
107
                // https://github.com/rust-lang/rust/issues/141510
108
                #[allow(ambiguous_wide_pointer_comparisons)]
109
                left.partial_cmp(&right)
9✔
110
            }))
9✔
111
            .ord(|| Some(|&left, &right| {
6✔
112
                #[allow(ambiguous_wide_pointer_comparisons)]
113
                left.cmp(&right)
6✔
114
            }))
6✔
UNCOV
115
            .hash(|| Some(|value, hasher_this, hasher_write_fn| {
×
UNCOV
116
                value.hash(&mut unsafe {
×
UNCOV
117
                    HasherProxy::new(hasher_this, hasher_write_fn)
×
UNCOV
118
                })
×
UNCOV
119
            }))
×
120
        => Raw, false
121
);
122

123
// *mut pointers
124
impl_facet_for_pointer!(
125
    Raw: *mut T
126
        => Shape::builder_for_sized::<Self>()
127
            .inner(|| T::SHAPE)
128
        => ValueVTable::builder::<Self>()
129
            .marker_traits(|| {
8✔
130
                let mut marker_traits = MarkerTraits::EQ
8✔
131
                    .union(MarkerTraits::COPY)
8✔
132
                    .union(MarkerTraits::UNPIN);
8✔
133

134
                if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE) {
8✔
135
                    marker_traits = marker_traits.union(MarkerTraits::UNWIND_SAFE).union(MarkerTraits::REF_UNWIND_SAFE);
6✔
136
                }
6✔
137

138
                marker_traits
8✔
139
            })
8✔
140
            .debug(|| Some(fmt::Debug::fmt))
48✔
141
            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
4✔
142
            .partial_eq(|| Some(|&left, &right| core::ptr::eq(left, right)))
5✔
143
            .partial_ord(|| Some(|&left, &right| {
5✔
144
                // https://github.com/rust-lang/rust/issues/141510
145
                #[allow(ambiguous_wide_pointer_comparisons)]
146
                left.partial_cmp(&right)
5✔
147
            }))
5✔
148
            .ord(|| Some(|&left, &right| {
4✔
149
                #[allow(ambiguous_wide_pointer_comparisons)]
150
                left.cmp(&right)
4✔
151
            }))
4✔
UNCOV
152
            .hash(|| Some(|value, hasher_this, hasher_write_fn| {
×
UNCOV
153
                value.hash(&mut unsafe {
×
UNCOV
154
                    HasherProxy::new(hasher_this, hasher_write_fn)
×
UNCOV
155
                })
×
UNCOV
156
            }))
×
157
        => Raw, true
158
);
159

160
// &T references
161
impl_facet_for_pointer!(
162
    Reference: &'a T
163
        => Shape::builder_for_sized::<Self>()
164
        => {
165
            ValueVTable::builder::<Self>()
166
                .marker_traits(|| {
22✔
167
                    let mut marker_traits = MarkerTraits::COPY.union(MarkerTraits::UNPIN);
22✔
168
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::EQ) {
22✔
169
                        marker_traits = marker_traits.union(MarkerTraits::EQ);
20✔
170
                    }
20✔
171
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SYNC) {
22✔
172
                        marker_traits = marker_traits.union(MarkerTraits::SEND).union(MarkerTraits::SYNC);
18✔
173
                    }
18✔
174
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE) {
22✔
175
                        marker_traits = marker_traits.union(MarkerTraits::UNWIND_SAFE).union(MarkerTraits::REF_UNWIND_SAFE);
20✔
176
                    }
20✔
177

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

245
// &mut T references
246
impl_facet_for_pointer!(
247
    Reference: &'a mut T
248
        => Shape::builder_for_sized::<Self>()
249
        => {
250
            ValueVTable::builder::<Self>()
251
                .marker_traits(|| {
6✔
252
                    let mut marker_traits = MarkerTraits::UNPIN;
6✔
253
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::EQ) {
6✔
254
                        marker_traits = marker_traits.union(MarkerTraits::EQ);
4✔
255
                    }
4✔
256
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SEND) {
6✔
257
                        marker_traits = marker_traits.union(MarkerTraits::SEND);
2✔
258
                    }
4✔
259
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SYNC) {
6✔
260
                        marker_traits = marker_traits.union(MarkerTraits::SYNC);
2✔
261
                    }
4✔
262
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE) {
6✔
263
                        marker_traits = marker_traits.union(MarkerTraits::REF_UNWIND_SAFE);
4✔
264
                    }
4✔
265

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

332
#[cfg(test)]
333
mod test {
334
    use core::panic::{RefUnwindSafe, UnwindSafe};
335
    use impls::impls;
336

337
    #[allow(unused)]
UNCOV
338
    const fn assert_impls_unwind_safe<T: UnwindSafe>() {}
×
339
    #[allow(unused)]
340
    const fn assert_impls_ref_unwind_safe<T: RefUnwindSafe>() {}
×
341

342
    #[allow(unused)]
343
    const fn ref_unwind_safe<T: RefUnwindSafe>() {
×
344
        assert_impls_unwind_safe::<&T>();
×
UNCOV
345
        assert_impls_ref_unwind_safe::<&T>();
×
346

UNCOV
347
        assert_impls_ref_unwind_safe::<&mut T>();
×
348

UNCOV
349
        assert_impls_unwind_safe::<*const T>();
×
UNCOV
350
        assert_impls_ref_unwind_safe::<*const T>();
×
351

UNCOV
352
        assert_impls_unwind_safe::<*mut T>();
×
UNCOV
353
        assert_impls_ref_unwind_safe::<*mut T>();
×
UNCOV
354
    }
×
355

356
    #[test]
357
    fn mut_ref_not_unwind_safe() {
1✔
358
        assert!(impls!(&mut (): !UnwindSafe));
1✔
359
    }
1✔
360
}
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