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

facet-rs / facet / 14653934267

25 Apr 2025 12:00AM UTC coverage: 49.49% (+0.2%) from 49.28%
14653934267

Pull #376

github

web-flow
Merge b3d6ab00c into 9e2670ec4
Pull Request #376: Implement Facet for references and pointers

171 of 293 new or added lines in 6 files covered. (58.36%)

4 existing lines in 2 files now uncovered.

6407 of 12946 relevant lines covered (49.49%)

65.21 hits per line

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

50.0
/facet-core/src/impls_core/refptr.rs
1
use core::alloc::Layout;
2

3
use crate::{
4
    ConstTypeId, Def, Facet, MarkerTraits, PtrConst, RefPtrDef, RefPtrMutability, RefPtrType,
5
    Shape, TypeNameFn, TypeParam, ValueVTable,
6
};
7

8
// TODO: Also implement for `T: !Facet<'a>`
9
unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for &'a T {
10
    const SHAPE: &'static Shape = &const {
11
        Shape::builder()
12
            .id(ConstTypeId::of::<Self>())
13
            .layout(Layout::new::<Self>())
14
            .type_params(&[TypeParam {
15
                name: "T",
16
                shape: || T::SHAPE,
1✔
17
            }])
18
            .vtable(
19
                &const {
20
                    let mut builder = ValueVTable::builder()
21
                        .type_name(|f, opts| {
4✔
22
                            if let Some(opts) = opts.for_children() {
4✔
23
                                write!(f, "&")?;
4✔
24
                                (T::SHAPE.vtable.type_name)(f, opts)
4✔
25
                            } else {
NEW
26
                                write!(f, "&⋯")
×
27
                            }
28
                        })
4✔
29
                        .drop_in_place(|value| unsafe { value.drop_in_place::<Self>() })
2✔
NEW
30
                        .clone_into(|src, dst| unsafe { dst.put(src.get::<Self>()) });
×
31

32
                    match T::SHAPE.def {
33
                        // Slice reference &[U]
34
                        Def::Slice(_) => {
35
                            builder = builder.default_in_place(|dst| {
2✔
36
                                const EMPTY: &[()] = &[];
37
                                unsafe { dst.put(EMPTY) }
2✔
38
                            });
2✔
39
                        }
40
                        Def::Str => {
NEW
41
                            builder = builder.default_in_place(|dst| unsafe { dst.put("") });
×
42
                        }
43
                        _ => {}
44
                    }
45
                    if T::SHAPE.vtable.debug.is_some() {
46
                        builder = builder.debug(|value, f| {
17✔
47
                            let value = unsafe { *value.get::<Self>() };
17✔
48
                            unsafe {
17✔
49
                                (T::SHAPE.vtable.debug.unwrap_unchecked())(PtrConst::new(value), f)
17✔
50
                            }
17✔
51
                        });
17✔
52
                    }
53

54
                    if T::SHAPE.vtable.eq.is_some() {
55
                        builder = builder.eq(|a, b| {
2✔
56
                            let a = unsafe { *a.get::<Self>() };
2✔
57
                            let b = unsafe { *b.get::<Self>() };
2✔
58
                            unsafe {
2✔
59
                                (T::SHAPE.vtable.eq.unwrap_unchecked())(
2✔
60
                                    PtrConst::new(a),
2✔
61
                                    PtrConst::new(b),
2✔
62
                                )
2✔
63
                            }
2✔
64
                        });
2✔
65
                    }
66

67
                    if T::SHAPE.vtable.ord.is_some() {
NEW
68
                        builder = builder.ord(|a, b| {
×
NEW
69
                            let a = unsafe { *a.get::<Self>() };
×
NEW
70
                            let b = unsafe { *b.get::<Self>() };
×
NEW
71
                            unsafe {
×
NEW
72
                                (T::SHAPE.vtable.ord.unwrap_unchecked())(
×
NEW
73
                                    PtrConst::new(a),
×
NEW
74
                                    PtrConst::new(b),
×
NEW
75
                                )
×
NEW
76
                            }
×
NEW
77
                        });
×
78
                    }
79

80
                    if T::SHAPE.vtable.partial_ord.is_some() {
81
                        builder = builder.partial_ord(|a, b| {
2✔
82
                            let a = unsafe { *a.get::<Self>() };
2✔
83
                            let b = unsafe { *b.get::<Self>() };
2✔
84
                            unsafe {
2✔
85
                                (T::SHAPE.vtable.partial_ord.unwrap_unchecked())(
2✔
86
                                    PtrConst::new(a),
2✔
87
                                    PtrConst::new(b),
2✔
88
                                )
2✔
89
                            }
2✔
90
                        });
2✔
91
                    }
92

93
                    if T::SHAPE.vtable.hash.is_some() {
NEW
94
                        builder = builder.hash(|value, state, hasher| {
×
NEW
95
                            let value = unsafe { *value.get::<Self>() };
×
NEW
96
                            unsafe {
×
NEW
97
                                (T::SHAPE.vtable.hash.unwrap_unchecked())(
×
NEW
98
                                    PtrConst::new(value),
×
NEW
99
                                    state,
×
NEW
100
                                    hasher,
×
NEW
101
                                )
×
NEW
102
                            }
×
NEW
103
                        });
×
104
                    }
105

106
                    let t_marker_traits = T::SHAPE.vtable.marker_traits;
107

108
                    let mut marker_traits = MarkerTraits::COPY.union(MarkerTraits::UNPIN);
109

110
                    if t_marker_traits.contains(MarkerTraits::EQ) {
111
                        marker_traits = marker_traits.union(MarkerTraits::EQ);
112
                    }
113
                    if t_marker_traits.contains(MarkerTraits::SYNC) {
114
                        marker_traits = marker_traits
115
                            .union(MarkerTraits::SEND)
116
                            .union(MarkerTraits::SYNC);
117
                    }
118

119
                    builder.marker_traits(marker_traits).build()
120
                },
121
            )
122
            .def(Def::RefPtr(
123
                RefPtrDef::builder()
124
                    .typ(RefPtrType::Reference)
125
                    .mutability(RefPtrMutability::Const)
126
                    .pointee(T::SHAPE)
127
                    .build(),
128
            ))
129
            .build()
130
    };
131
}
132

133
unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for &'a mut T {
134
    const SHAPE: &'static Shape = &const {
135
        Shape::builder()
136
            .id(ConstTypeId::of::<Self>())
137
            .layout(Layout::new::<Self>())
138
            .type_params(&[TypeParam {
139
                name: "T",
NEW
140
                shape: || T::SHAPE,
×
141
            }])
142
            .vtable(
143
                &const {
144
                    let ref_vtable = <&T as Facet>::SHAPE.vtable;
NEW
145
                    let type_name: TypeNameFn = |f, opts| {
×
NEW
146
                        if let Some(opts) = opts.for_children() {
×
NEW
147
                            write!(f, "&mut ")?;
×
NEW
148
                            (T::SHAPE.vtable.type_name)(f, opts)
×
149
                        } else {
NEW
150
                            write!(f, "&mut ⋯")
×
151
                        }
NEW
152
                    };
×
153

154
                    let t_marker_traits = T::SHAPE.vtable.marker_traits;
155

156
                    let mut marker_traits = MarkerTraits::UNPIN;
157

158
                    if t_marker_traits.contains(MarkerTraits::EQ) {
159
                        marker_traits = marker_traits.union(MarkerTraits::EQ);
160
                    }
161
                    if t_marker_traits.contains(MarkerTraits::SEND) {
162
                        marker_traits = marker_traits.union(MarkerTraits::SEND);
163
                    }
164
                    if t_marker_traits.contains(MarkerTraits::SYNC) {
165
                        marker_traits = marker_traits.union(MarkerTraits::SYNC);
166
                    }
167

168
                    ValueVTable {
169
                        type_name,
170
                        marker_traits,
171
                        ..*ref_vtable
172
                    }
173
                },
174
            )
175
            .def(Def::RefPtr(
176
                RefPtrDef::builder()
177
                    .typ(RefPtrType::Reference)
178
                    .mutability(RefPtrMutability::Mut)
179
                    .pointee(T::SHAPE)
180
                    .build(),
181
            ))
182
            .build()
183
    };
184
}
185

186
unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for *const T {
187
    const SHAPE: &'static Shape = &const {
188
        Shape::builder()
189
            .id(ConstTypeId::of::<Self>())
190
            .layout(Layout::new::<Self>())
191
            .type_params(&[TypeParam {
192
                name: "T",
NEW
193
                shape: || T::SHAPE,
×
194
            }])
195
            .vtable(
196
                &const {
197
                    let builder = ValueVTable::builder()
NEW
198
                        .type_name(|f, opts| {
×
NEW
199
                            if let Some(opts) = opts.for_children() {
×
NEW
200
                                write!(f, "*const ")?;
×
NEW
201
                                (T::SHAPE.vtable.type_name)(f, opts)
×
202
                            } else {
NEW
203
                                write!(f, "*const ⋯")
×
204
                            }
NEW
205
                        })
×
206
                        .debug(|value, f| {
1✔
207
                            let v = unsafe { value.get::<Self>() };
1✔
208
                            write!(f, "{v:?}")
1✔
209
                        });
1✔
210

211
                    // Pointers aren't guaranteed to be valid, so we can't implement most functions
212

213
                    // TODO: Marker traits
214
                    // builder = builder.marker_traits(traits);
215

216
                    builder.build()
217
                },
218
            )
219
            .def(Def::RefPtr(
220
                RefPtrDef::builder()
221
                    .typ(RefPtrType::Pointer)
222
                    .mutability(RefPtrMutability::Const)
223
                    .pointee(T::SHAPE)
224
                    .build(),
225
            ))
226
            .build()
227
    };
228
}
229

230
unsafe impl<'a, T: Facet<'a> + ?Sized> Facet<'a> for *mut T {
231
    const SHAPE: &'static Shape = &const {
232
        Shape::builder()
233
            .id(ConstTypeId::of::<Self>())
234
            .layout(Layout::new::<Self>())
235
            .type_params(&[TypeParam {
236
                name: "T",
NEW
237
                shape: || T::SHAPE,
×
238
            }])
239
            .vtable(
240
                &const {
241
                    let builder = ValueVTable::builder()
NEW
242
                        .type_name(|f, opts| {
×
NEW
243
                            if let Some(opts) = opts.for_children() {
×
NEW
244
                                write!(f, "*mut ")?;
×
NEW
245
                                (T::SHAPE.vtable.type_name)(f, opts)
×
246
                            } else {
NEW
247
                                write!(f, "*mut ⋯")
×
248
                            }
NEW
249
                        })
×
250
                        .debug(|value, f| {
1✔
251
                            let v = unsafe { value.get::<Self>() };
1✔
252
                            write!(f, "{v:?}")
1✔
253
                        });
1✔
254

255
                    // Pointers aren't guaranteed to be valid, so we can't implement most functions
256

257
                    // TODO: Marker traits
258
                    // builder = builder.marker_traits(traits);
259

260
                    builder.build()
261
                },
262
            )
263
            .def(Def::RefPtr(
264
                RefPtrDef::builder()
265
                    .typ(RefPtrType::Pointer)
266
                    .mutability(RefPtrMutability::Mut)
267
                    .pointee(T::SHAPE)
268
                    .build(),
269
            ))
270
            .build()
271
    };
272
}
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