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

facet-rs / facet / 15229493257

24 May 2025 05:40PM UTC coverage: 57.747% (+0.01%) from 57.737%
15229493257

Pull #675

github

web-flow
Merge b33837f1a into bd1cec748
Pull Request #675: Fix wide pointer comparisons

10 of 10 new or added lines in 1 file covered. (100.0%)

2 existing lines in 1 file now uncovered.

10026 of 17362 relevant lines covered (57.75%)

141.15 hits per line

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

76.19
/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 ")?;
8✔
19
                                } else {
20
                                    write!(f, "*const ")?;
16✔
21
                                }
22
                            } else {
23
                                write!(f, "&")?;
45✔
24
                                if $mutable {
25
                                    write!(f, "mut ")?;
8✔
26
                                }
37✔
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(||
93
                MarkerTraits::EQ
94
                    .union(MarkerTraits::COPY)
14✔
95
                    .union(MarkerTraits::UNPIN),
14✔
96
            )
97
            .debug(|| Some(fmt::Debug::fmt))
102✔
98
            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
3✔
99
            .eq(|| Some(|&left, &right| core::ptr::eq(left, right)))
8✔
100
            .partial_ord(|| Some(|&left, &right| {
8✔
101
                // https://github.com/rust-lang/rust/issues/141510
102
                #[allow(ambiguous_wide_pointer_comparisons)]
103
                left.partial_cmp(&right)
8✔
104
            }))
8✔
105
            .ord(|| Some(|&left, &right| {
5✔
106
                #[allow(ambiguous_wide_pointer_comparisons)]
107
                left.cmp(&right)
5✔
108
            }))
5✔
UNCOV
109
            .hash(|| Some(|value, hasher_this, hasher_write_fn| {
×
110
                value.hash(&mut unsafe {
×
111
                    HasherProxy::new(hasher_this, hasher_write_fn)
×
112
                })
×
113
            }))
×
114
        => Raw, false
115
);
116

117
// *mut pointers
118
impl_facet_for_pointer!(
119
    Raw: *mut T
120
        => Shape::builder_for_sized::<Self>()
121
            .inner(|| T::SHAPE)
122
        => ValueVTable::builder::<Self>()
123
            .marker_traits(||
124
                MarkerTraits::EQ
125
                    .union(MarkerTraits::COPY)
4✔
126
                    .union(MarkerTraits::UNPIN),
4✔
127
            )
128
            .debug(|| Some(fmt::Debug::fmt))
38✔
129
            .clone_into(|| Some(|src, dst| unsafe { dst.put(*src) }))
3✔
130
            .eq(|| Some(|&left, &right| core::ptr::eq(left, right)))
4✔
131
            .partial_ord(|| Some(|&left, &right| {
4✔
132
                // https://github.com/rust-lang/rust/issues/141510
133
                #[allow(ambiguous_wide_pointer_comparisons)]
134
                left.partial_cmp(&right)
4✔
135
            }))
4✔
136
            .ord(|| Some(|&left, &right| {
3✔
137
                #[allow(ambiguous_wide_pointer_comparisons)]
138
                left.cmp(&right)
3✔
139
            }))
3✔
UNCOV
140
            .hash(|| Some(|value, hasher_this, hasher_write_fn| {
×
141
                value.hash(&mut unsafe {
×
142
                    HasherProxy::new(hasher_this, hasher_write_fn)
×
143
                })
×
144
            }))
×
145
        => Raw, true
146
);
147

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

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

230
// &mut T references
231
impl_facet_for_pointer!(
232
    Reference: &'a mut T
233
        => Shape::builder_for_sized::<Self>()
234
        => {
235
            ValueVTable::builder::<Self>()
236
                .marker_traits(|| {
4✔
237
                    let mut marker_traits = MarkerTraits::UNPIN;
4✔
238
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::EQ) {
4✔
239
                        marker_traits = marker_traits.union(MarkerTraits::EQ);
4✔
240
                    }
4✔
241
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SEND) {
4✔
242
                        marker_traits = marker_traits.union(MarkerTraits::SEND);
2✔
243
                    }
2✔
244
                    if T::SHAPE.vtable.marker_traits().contains(MarkerTraits::SYNC) {
4✔
245
                        marker_traits = marker_traits.union(MarkerTraits::SYNC);
2✔
246
                    }
2✔
247

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