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

facet-rs / facet / 15156680423

21 May 2025 07:53AM UTC coverage: 57.743% (+0.2%) from 57.59%
15156680423

push

github

fasterthanlime
Fix marker traits for references and also test marker traits in facts

9441 of 16350 relevant lines covered (57.74%)

137.46 hits per line

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

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

3
use crate::{
4
    Facet, HasherProxy, MarkerTraits, PointerType, Shape, Type, TypeParam, ValuePointerType,
5
    ValueVTable,
6
};
7

8
macro_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| {
33✔
14
                        if let Some(opts) = opts.for_children() {
33✔
15
                            if stringify!($ptr_type) == "Raw" {
33✔
16
                                if $mutable {
17
                                    write!(f, "*mut ")?;
2✔
18
                                } else {
19
                                    write!(f, "*const ")?;
6✔
20
                                }
21
                            } else {
22
                                write!(f, "&")?;
25✔
23
                                if $mutable {
24
                                    write!(f, "mut ")?;
4✔
25
                                }
21✔
26
                            }
27
                            (T::VTABLE.type_name)(f, opts)
33✔
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
                    })
33✔
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

71
// *const pointers
72
impl_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::<()>()))
3✔
85
            .partial_ord(|&left, &right| {
3✔
86
                left.cast::<()>().partial_cmp(&right.cast::<()>())
3✔
87
            })
3✔
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

97
// *mut pointers
98
impl_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::<()>()))
1✔
111
            .partial_ord(|&left, &right| {
1✔
112
                left.cast::<()>().partial_cmp(&right.cast::<()>())
1✔
113
            })
1✔
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

123
// &T references
124
impl_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
            // Forward trait methods to the underlying type if it implements them
141
            if T::VTABLE.debug.is_some() {
142
                builder = builder.debug(|value, f| {
48✔
143
                    let target_ptr = crate::PtrConst::new(value);
48✔
144
                    unsafe { (T::VTABLE.debug.unwrap())(target_ptr, f) }
48✔
145
                });
48✔
146
            }
147

148
            if T::VTABLE.display.is_some() {
149
                builder = builder.display(|value, f| {
14✔
150
                    let target_ptr = crate::PtrConst::new(value);
14✔
151
                    unsafe { (T::VTABLE.display.unwrap())(target_ptr, f) }
14✔
152
                });
14✔
153
            }
154

155
            if T::VTABLE.eq.is_some() {
156
                builder = builder.eq(|a, b| {
7✔
157
                    let a_ptr = crate::PtrConst::new(a);
7✔
158
                    let b_ptr = crate::PtrConst::new(b);
7✔
159
                    unsafe { (T::VTABLE.eq.unwrap())(a_ptr, b_ptr) }
7✔
160
                });
7✔
161
            }
162

163
            if T::VTABLE.partial_ord.is_some() {
164
                builder = builder.partial_ord(|a, b| {
7✔
165
                    let a_ptr = crate::PtrConst::new(a);
7✔
166
                    let b_ptr = crate::PtrConst::new(b);
7✔
167
                    unsafe { (T::VTABLE.partial_ord.unwrap())(a_ptr, b_ptr) }
7✔
168
                });
7✔
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

191
// &mut T references
192
impl_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
            // Forward trait methods to the underlying type if it implements them
211
            if T::VTABLE.debug.is_some() {
212
                builder = builder.debug(|value, f| {
12✔
213
                    let target_ptr = crate::PtrConst::new(value);
12✔
214
                    unsafe { (T::VTABLE.debug.unwrap())(target_ptr, f) }
12✔
215
                });
12✔
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| {
2✔
227
                    let a_ptr = crate::PtrConst::new(a);
2✔
228
                    let b_ptr = crate::PtrConst::new(b);
2✔
229
                    unsafe { (T::VTABLE.eq.unwrap())(a_ptr, b_ptr) }
2✔
230
                });
2✔
231
            }
232

233
            if T::VTABLE.partial_ord.is_some() {
234
                builder = builder.partial_ord(|a, b| {
2✔
235
                    let a_ptr = crate::PtrConst::new(a);
2✔
236
                    let b_ptr = crate::PtrConst::new(b);
2✔
237
                    unsafe { (T::VTABLE.partial_ord.unwrap())(a_ptr, b_ptr) }
2✔
238
                });
2✔
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
);
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