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

facet-rs / facet / 18683512809

21 Oct 2025 12:16PM UTC coverage: 53.804% (-0.2%) from 54.052%
18683512809

push

github

fasterthanlime
remove fn() layer of indirection where possible

100 of 260 new or added lines in 30 files covered. (38.46%)

22 existing lines in 5 files now uncovered.

4590 of 8531 relevant lines covered (53.8%)

41.11 hits per line

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

1.65
/facet-core/src/types/def/pointer.rs
1
use bitflags::bitflags;
2

3
use crate::{PtrConst, PtrMut, PtrUninit};
4

5
use super::Shape;
6

7
/// Describes a pointer — including a vtable to query and alter its state,
8
/// and the inner shape (the pointee type in the pointer).
9
#[derive(Clone, Copy, Debug)]
10
#[repr(C)]
11
pub struct PointerDef {
12
    /// vtable for interacting with the pointer
13
    pub vtable: &'static PointerVTable,
14

15
    /// shape of the inner type of the pointer, if not opaque
16
    pub pointee: Option<&'static Shape>,
17

18
    /// shape of the corresponding strong pointer, if this pointer is weak
19
    ///
20
    /// the layer of indirection is to break the strong <-> weak reference cycle,
21
    /// since consts may not have cycles in their definitions.
22
    pub weak: Option<fn() -> &'static Shape>,
23

24
    /// shape of the corresponding weak pointer, if this pointer is strong
25
    pub strong: Option<&'static Shape>,
26

27
    /// Flags representing various characteristics of the pointer
28
    pub flags: PointerFlags,
29

30
    /// An optional field to identify the kind of pointer
31
    pub known: Option<KnownPointer>,
32
}
33

34
impl PointerDef {
35
    /// Creates a new `PointerDefBuilder` with all fields set to `None`.
36
    #[must_use]
37
    pub const fn builder() -> PointerDefBuilder {
×
38
        PointerDefBuilder {
×
39
            vtable: None,
×
40
            pointee: None,
×
41
            flags: None,
×
42
            known: None,
×
43
            weak: None,
×
44
            strong: None,
×
45
        }
×
46
    }
×
47

48
    /// Returns shape of the inner type of the pointer, if not opaque
49
    pub fn pointee(&self) -> Option<&'static Shape> {
48✔
50
        self.pointee
48✔
51
    }
48✔
52

53
    /// Returns shape of the corresponding strong pointer, if this pointer is weak
54
    pub fn weak(&self) -> Option<&'static Shape> {
×
NEW
55
        self.weak.map(|f| f())
×
56
    }
×
57

58
    /// Returns shape of the corresponding weak pointer, if this pointer is strong
59
    pub fn strong(&self) -> Option<&'static Shape> {
×
NEW
60
        self.strong
×
61
    }
×
62
}
63

64
/// Builder for creating a `PointerDef`.
65
#[derive(Debug)]
66
pub struct PointerDefBuilder {
67
    vtable: Option<&'static PointerVTable>,
68
    pointee: Option<&'static Shape>,
69
    flags: Option<PointerFlags>,
70
    known: Option<KnownPointer>,
71
    weak: Option<fn() -> &'static Shape>,
72
    strong: Option<&'static Shape>,
73
}
74

75
impl PointerDefBuilder {
76
    /// Creates a new `PointerDefBuilder` with all fields set to `None`.
77
    #[must_use]
78
    #[expect(clippy::new_without_default)]
79
    pub const fn new() -> Self {
×
80
        Self {
×
81
            vtable: None,
×
82
            pointee: None,
×
83
            flags: None,
×
84
            known: None,
×
85
            weak: None,
×
86
            strong: None,
×
87
        }
×
88
    }
×
89

90
    /// Sets the vtable for the pointer.
91
    #[must_use]
92
    pub const fn vtable(mut self, vtable: &'static PointerVTable) -> Self {
×
93
        self.vtable = Some(vtable);
×
94
        self
×
95
    }
×
96

97
    /// Sets the shape of the inner type of the pointer.
98
    #[must_use]
NEW
99
    pub const fn pointee(mut self, pointee: &'static Shape) -> Self {
×
100
        self.pointee = Some(pointee);
×
101
        self
×
102
    }
×
103

104
    /// Sets the flags for the pointer.
105
    #[must_use]
106
    pub const fn flags(mut self, flags: PointerFlags) -> Self {
×
107
        self.flags = Some(flags);
×
108
        self
×
109
    }
×
110

111
    /// Sets the known pointer type.
112
    #[must_use]
113
    pub const fn known(mut self, known: KnownPointer) -> Self {
×
114
        self.known = Some(known);
×
115
        self
×
116
    }
×
117

118
    /// Sets the shape of the corresponding weak pointer, if this pointer is strong.
119
    #[must_use]
120
    pub const fn weak(mut self, weak: fn() -> &'static Shape) -> Self {
×
121
        self.weak = Some(weak);
×
122
        self
×
123
    }
×
124

125
    /// Sets the shape of the corresponding strong pointer, if this pointer is weak
126
    #[must_use]
NEW
127
    pub const fn strong(mut self, strong: &'static Shape) -> Self {
×
128
        self.strong = Some(strong);
×
129
        self
×
130
    }
×
131

132
    /// Builds a `PointerDef` from the provided configuration.
133
    ///
134
    /// # Panics
135
    ///
136
    /// Panics if any required field (vtable, flags) is not set.
137
    #[must_use]
138
    pub const fn build(self) -> PointerDef {
×
139
        PointerDef {
×
140
            vtable: self.vtable.unwrap(),
×
141
            pointee: self.pointee,
×
142
            weak: self.weak,
×
143
            strong: self.strong,
×
144
            flags: self.flags.unwrap(),
×
145
            known: self.known,
×
146
        }
×
147
    }
×
148
}
149

150
bitflags! {
151
    /// Flags to represent various characteristics of pointers
152
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
153
    pub struct PointerFlags: u8 {
154
        /// An empty set of flags
155
        const EMPTY = 0;
156

157
        /// Whether the pointer is weak (like [`std::sync::Weak`])
158
        const WEAK = 1 << 0;
159
        /// Whether the pointer is atomic (like [`std::sync::Arc`])
160
        const ATOMIC = 1 << 1;
161
        /// Whether the pointer is a lock (like [`std::sync::Mutex`])
162
        const LOCK = 1 << 2;
163
    }
164
}
165

166
/// Tries to upgrade the weak pointer to a strong one.
167
///
168
/// If the upgrade succeeds, initializes the pointer into the given `strong`, and returns a
169
/// copy of `strong`, which has been guaranteed to be initialized. If the upgrade fails, `None` is
170
/// returned and `strong` is not initialized.
171
///
172
/// `weak` is not moved out of.
173
///
174
/// # Safety
175
///
176
/// `weak` must be a valid weak pointer (like [`std::sync::Weak`] or [`std::rc::Weak`]).
177
///
178
/// `strong` must be allocated, and of the right layout for the corresponding pointer.
179
///
180
/// `strong` must not have been initialized yet.
181
pub type UpgradeIntoFn =
182
    for<'ptr> unsafe fn(weak: PtrMut<'ptr>, strong: PtrUninit<'ptr>) -> Option<PtrMut<'ptr>>;
183

184
/// Downgrades a strong pointer to a weak one.
185
///
186
/// Initializes the pointer into the given `weak`, and returns a copy of `weak`, which has
187
/// been guaranteed to be initialized.
188
///
189
/// Only strong pointers can be downgraded (like [`std::sync::Arc`] or [`std::rc::Rc`]).
190
///
191
/// # Safety
192
///
193
/// `strong` must be a valid strong pointer (like [`std::sync::Arc`] or [`std::rc::Rc`]).
194
///
195
/// `weak` must be allocated, and of the right layout for the corresponding weak pointer.
196
///
197
/// `weak` must not have been initialized yet.
198
pub type DowngradeIntoFn =
199
    for<'ptr> unsafe fn(strong: PtrMut<'ptr>, weak: PtrUninit<'ptr>) -> PtrMut<'ptr>;
200

201
/// Tries to obtain a reference to the inner value of the pointer.
202
///
203
/// This can only be used with strong pointers (like [`std::sync::Arc`] or [`std::rc::Rc`]).
204
///
205
/// # Safety
206
///
207
/// `this` must be a valid strong pointer (like [`std::sync::Arc`] or [`std::rc::Rc`]).
208
pub type BorrowFn = for<'ptr> unsafe fn(this: PtrConst<'ptr>) -> PtrConst<'ptr>;
209

210
/// Creates a new pointer wrapping the given value.
211
///
212
/// Initializes the pointer into the given `this`, and returns a copy of `this`, which has
213
/// been guaranteed to be initialized.
214
///
215
/// This can only be used with strong pointers (like [`std::sync::Arc`] or [`std::rc::Rc`]).
216
///
217
/// # Safety
218
///
219
/// `this` must be allocated, and of the right layout for the corresponding pointer.
220
///
221
/// `this` must not have been initialized yet.
222
///
223
/// `ptr` must point to a value of type `T`.
224
///
225
/// `ptr` is moved out of (with [`core::ptr::read`]) — it should be deallocated afterwards (e.g.
226
/// with [`core::mem::forget`]) but NOT dropped).
227
pub type NewIntoFn = for<'ptr> unsafe fn(this: PtrUninit<'ptr>, ptr: PtrMut<'ptr>) -> PtrMut<'ptr>;
228

229
/// Type-erased result of locking a mutex-like pointer
230
pub struct LockResult<'ptr> {
231
    /// The data that was locked
232
    data: PtrMut<'ptr>,
233
    /// The guard that protects the data
234
    guard: PtrConst<'ptr>,
235
    /// The vtable for the guard
236
    guard_vtable: &'static LockGuardVTable,
237
}
238

239
impl<'ptr> LockResult<'ptr> {
240
    /// Returns a reference to the locked data
241
    #[must_use]
242
    pub fn data(&self) -> &PtrMut<'ptr> {
×
243
        &self.data
×
244
    }
×
245
}
246

247
impl Drop for LockResult<'_> {
248
    fn drop(&mut self) {
×
249
        unsafe {
×
250
            (self.guard_vtable.drop_in_place)(self.guard);
×
251
        }
×
252
    }
×
253
}
254

255
/// Functions for manipulating a guard
256
pub struct LockGuardVTable {
257
    /// Drops the guard in place
258
    pub drop_in_place: for<'ptr> unsafe fn(guard: PtrConst<'ptr>),
259
}
260

261
/// Acquires a lock on a mutex-like pointer
262
pub type LockFn = for<'ptr> unsafe fn(opaque: PtrConst<'ptr>) -> Result<LockResult<'ptr>, ()>;
263

264
/// Acquires a read lock on a reader-writer lock-like pointer
265
pub type ReadFn = for<'ptr> unsafe fn(opaque: PtrConst<'ptr>) -> Result<LockResult<'ptr>, ()>;
266

267
/// Acquires a write lock on a reader-writer lock-like pointer
268
pub type WriteFn = for<'ptr> unsafe fn(opaque: PtrConst<'ptr>) -> Result<LockResult<'ptr>, ()>;
269

270
/// Creates a new slice builder for a pointer: ie. for `Arc<[u8]>`, it builds a
271
/// `Vec<u8>` internally, to which you can push, and then turn into an `Arc<[u8]>` at
272
/// the last stage.
273
///
274
/// This works for any `U` in `Arc<[U]>` because those have separate concrete implementations, and
275
/// thus, separate concrete vtables.
276
pub type SliceBuilderNewFn = fn() -> PtrMut<'static>;
277

278
/// Pushes a value into a slice builder.
279
///
280
/// # Safety
281
///
282
/// Item must point to a valid value of type `U` and must be initialized.
283
/// Function is infallible as it uses the global allocator.
284
pub type SliceBuilderPushFn = unsafe fn(builder: PtrMut, item: PtrMut);
285

286
/// Converts a slice builder into a pointer. This takes ownership of the builder
287
/// and frees the backing storage.
288
///
289
/// # Safety
290
///
291
/// The builder must be valid and must not be used after this function is called.
292
/// Function is infallible as it uses the global allocator.
293
pub type SliceBuilderConvertFn = unsafe fn(builder: PtrMut<'static>) -> PtrConst<'static>;
294

295
/// Frees a slice builder without converting it into a pointer
296
///
297
/// # Safety
298
///
299
/// The builder must be valid and must not be used after this function is called.
300
pub type SliceBuilderFreeFn = unsafe fn(builder: PtrMut<'static>);
301

302
/// Functions for creating and manipulating slice builders.
303
#[derive(Debug, Clone, Copy)]
304
pub struct SliceBuilderVTable {
305
    /// See [`SliceBuilderNewFn`]
306
    pub new_fn: SliceBuilderNewFn,
307
    /// See [`SliceBuilderPushFn`]
308
    pub push_fn: SliceBuilderPushFn,
309
    /// See [`SliceBuilderConvertFn`]
310
    pub convert_fn: SliceBuilderConvertFn,
311
    /// See [`SliceBuilderFreeFn`]
312
    pub free_fn: SliceBuilderFreeFn,
313
}
314

315
impl SliceBuilderVTable {
316
    /// Creates a new `SliceBuilderVTableBuilder` with all fields set to `None`.
317
    #[must_use]
318
    pub const fn builder() -> SliceBuilderVTableBuilder {
×
319
        SliceBuilderVTableBuilder {
×
320
            new_fn: None,
×
321
            push_fn: None,
×
322
            convert_fn: None,
×
323
            free_fn: None,
×
324
        }
×
325
    }
×
326
}
327

328
/// Builder for creating a `SliceBuilderVTable`.
329
#[derive(Debug)]
330
pub struct SliceBuilderVTableBuilder {
331
    new_fn: Option<SliceBuilderNewFn>,
332
    push_fn: Option<SliceBuilderPushFn>,
333
    convert_fn: Option<SliceBuilderConvertFn>,
334
    free_fn: Option<SliceBuilderFreeFn>,
335
}
336

337
impl SliceBuilderVTableBuilder {
338
    /// Creates a new `SliceBuilderVTableBuilder` with all fields set to `None`.
339
    #[must_use]
340
    #[expect(clippy::new_without_default)]
341
    pub const fn new() -> Self {
×
342
        Self {
×
343
            new_fn: None,
×
344
            push_fn: None,
×
345
            convert_fn: None,
×
346
            free_fn: None,
×
347
        }
×
348
    }
×
349

350
    /// Sets the `new` function for the slice builder.
351
    #[must_use]
352
    pub const fn new_fn(mut self, new_fn: SliceBuilderNewFn) -> Self {
×
353
        self.new_fn = Some(new_fn);
×
354
        self
×
355
    }
×
356

357
    /// Sets the `push` function for the slice builder.
358
    #[must_use]
359
    pub const fn push_fn(mut self, push_fn: SliceBuilderPushFn) -> Self {
×
360
        self.push_fn = Some(push_fn);
×
361
        self
×
362
    }
×
363

364
    /// Sets the `convert` function for the slice builder.
365
    #[must_use]
366
    pub const fn convert_fn(mut self, convert_fn: SliceBuilderConvertFn) -> Self {
×
367
        self.convert_fn = Some(convert_fn);
×
368
        self
×
369
    }
×
370

371
    /// Sets the `free` function for the slice builder.
372
    #[must_use]
373
    pub const fn free_fn(mut self, free_fn: SliceBuilderFreeFn) -> Self {
×
374
        self.free_fn = Some(free_fn);
×
375
        self
×
376
    }
×
377

378
    /// Builds a `SliceBuilderVTable` from the provided configuration.
379
    #[must_use]
380
    pub const fn build(self) -> SliceBuilderVTable {
×
381
        SliceBuilderVTable {
×
382
            new_fn: self.new_fn.expect("new_fn must be set"),
×
383
            push_fn: self.push_fn.expect("push_fn must be set"),
×
384
            convert_fn: self.convert_fn.expect("convert_fn must be set"),
×
385
            free_fn: self.free_fn.expect("free_fn must be set"),
×
386
        }
×
387
    }
×
388
}
389

390
/// Functions for interacting with a pointer
391
#[derive(Debug, Clone, Copy)]
392
pub struct PointerVTable {
393
    /// See [`UpgradeIntoFn`]
394
    pub upgrade_into_fn: Option<UpgradeIntoFn>,
395

396
    /// See [`DowngradeIntoFn`]
397
    pub downgrade_into_fn: Option<DowngradeIntoFn>,
398

399
    /// See [`BorrowFn`]
400
    pub borrow_fn: Option<BorrowFn>,
401

402
    /// See [`NewIntoFn`]
403
    pub new_into_fn: Option<NewIntoFn>,
404

405
    /// See [`LockFn`]
406
    pub lock_fn: Option<LockFn>,
407

408
    /// See [`ReadFn`]
409
    pub read_fn: Option<ReadFn>,
410

411
    /// See [`WriteFn`]
412
    pub write_fn: Option<WriteFn>,
413

414
    /// See [`SliceBuilderVTable`]
415
    pub slice_builder_vtable: Option<&'static SliceBuilderVTable>,
416
}
417

418
impl PointerVTable {
419
    /// Creates a new `PointerVTableBuilder` with all fields set to `None`.
420
    #[must_use]
421
    pub const fn builder() -> PointerVTableBuilder {
×
422
        PointerVTableBuilder {
×
423
            upgrade_into_fn: None,
×
424
            downgrade_into_fn: None,
×
425
            borrow_fn: None,
×
426
            new_into_fn: None,
×
427
            lock_fn: None,
×
428
            read_fn: None,
×
429
            write_fn: None,
×
430
            slice_builder_vtable: None,
×
431
        }
×
432
    }
×
433
}
434

435
/// Builder for creating a `PointerVTable`.
436
#[derive(Debug)]
437
pub struct PointerVTableBuilder {
438
    upgrade_into_fn: Option<UpgradeIntoFn>,
439
    downgrade_into_fn: Option<DowngradeIntoFn>,
440
    borrow_fn: Option<BorrowFn>,
441
    new_into_fn: Option<NewIntoFn>,
442
    lock_fn: Option<LockFn>,
443
    read_fn: Option<ReadFn>,
444
    write_fn: Option<WriteFn>,
445
    slice_builder_vtable: Option<&'static SliceBuilderVTable>,
446
}
447

448
impl PointerVTableBuilder {
449
    /// Creates a new `PointerVTableBuilder` with all fields set to `None`.
450
    #[must_use]
451
    #[expect(clippy::new_without_default)]
452
    pub const fn new() -> Self {
×
453
        Self {
×
454
            upgrade_into_fn: None,
×
455
            downgrade_into_fn: None,
×
456
            borrow_fn: None,
×
457
            new_into_fn: None,
×
458
            lock_fn: None,
×
459
            read_fn: None,
×
460
            write_fn: None,
×
461
            slice_builder_vtable: None,
×
462
        }
×
463
    }
×
464

465
    /// Sets the `try_upgrade` function.
466
    #[must_use]
467
    pub const fn upgrade_into_fn(mut self, upgrade_into_fn: UpgradeIntoFn) -> Self {
×
468
        self.upgrade_into_fn = Some(upgrade_into_fn);
×
469
        self
×
470
    }
×
471

472
    /// Sets the `downgrade` function.
473
    #[must_use]
474
    pub const fn downgrade_into_fn(mut self, downgrade_into_fn: DowngradeIntoFn) -> Self {
×
475
        self.downgrade_into_fn = Some(downgrade_into_fn);
×
476
        self
×
477
    }
×
478

479
    /// Sets the `borrow` function.
480
    #[must_use]
481
    pub const fn borrow_fn(mut self, borrow_fn: BorrowFn) -> Self {
×
482
        self.borrow_fn = Some(borrow_fn);
×
483
        self
×
484
    }
×
485

486
    /// Sets the `new_into` function.
487
    #[must_use]
488
    pub const fn new_into_fn(mut self, new_into_fn: NewIntoFn) -> Self {
×
489
        self.new_into_fn = Some(new_into_fn);
×
490
        self
×
491
    }
×
492

493
    /// Sets the `lock` function.
494
    #[must_use]
495
    pub const fn lock_fn(mut self, lock_fn: LockFn) -> Self {
×
496
        self.lock_fn = Some(lock_fn);
×
497
        self
×
498
    }
×
499

500
    /// Sets the `read` function.
501
    #[must_use]
502
    pub const fn read_fn(mut self, read_fn: ReadFn) -> Self {
×
503
        self.read_fn = Some(read_fn);
×
504
        self
×
505
    }
×
506

507
    /// Sets the `write` function.
508
    #[must_use]
509
    pub const fn write_fn(mut self, write_fn: WriteFn) -> Self {
×
510
        self.write_fn = Some(write_fn);
×
511
        self
×
512
    }
×
513

514
    /// Sets the `slice_builder_vtable` function.
515
    #[must_use]
516
    pub const fn slice_builder_vtable(
×
517
        mut self,
×
518
        slice_builder_vtable: &'static SliceBuilderVTable,
×
519
    ) -> Self {
×
520
        self.slice_builder_vtable = Some(slice_builder_vtable);
×
521
        self
×
522
    }
×
523

524
    /// Builds a `PointerVTable` from the provided configuration.
525
    #[must_use]
526
    pub const fn build(self) -> PointerVTable {
×
527
        PointerVTable {
×
528
            upgrade_into_fn: self.upgrade_into_fn,
×
529
            downgrade_into_fn: self.downgrade_into_fn,
×
530
            borrow_fn: self.borrow_fn,
×
531
            new_into_fn: self.new_into_fn,
×
532
            lock_fn: self.lock_fn,
×
533
            read_fn: self.read_fn,
×
534
            write_fn: self.write_fn,
×
535
            slice_builder_vtable: self.slice_builder_vtable,
×
536
        }
×
537
    }
×
538
}
539

540
/// Represents common standard library pointer kinds
541
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
542
pub enum KnownPointer {
543
    /// [`Box<T>`](std::boxed::Box), heap-allocated values with single ownership
544
    Box,
545
    /// [`Rc<T>`](std::rc::Rc), reference-counted values with multiple ownership
546
    Rc,
547
    /// [`Weak<T>`](std::rc::Weak), a weak reference to an `Rc`-managed value
548
    RcWeak,
549
    /// [`Arc<T>`](std::sync::Arc), thread-safe reference-counted values with multiple ownership
550
    Arc,
551
    /// [`Weak<T>`](std::sync::Weak), a weak reference to an `Arc`-managed value
552
    ArcWeak,
553
    /// [`Cow<'a, T>`](std::borrow::Cow), a clone-on-write smart pointer
554
    Cow,
555
    /// [`Pin<P>`](std::pin::Pin), a type that pins values behind a pointer
556
    Pin,
557
    /// [`Cell<T>`](std::cell::Cell), a mutable memory location with interior mutability
558
    Cell,
559
    /// [`RefCell<T>`](std::cell::RefCell), a mutable memory location with dynamic borrowing rules
560
    RefCell,
561
    /// [`OnceCell<T>`](std::cell::OnceCell), a cell that can be written to only once
562
    OnceCell,
563
    /// [`Mutex<T>`](std::sync::Mutex), a mutual exclusion primitive
564
    Mutex,
565
    /// [`RwLock<T>`](std::sync::RwLock), a reader-writer lock
566
    RwLock,
567
    /// [`NonNull<T>`](core::ptr::NonNull), a wrapper around a raw pointer that is not null
568
    NonNull,
569
    /// `&T`
570
    SharedReference,
571
    /// `&mut T`
572
    ExclusiveReference,
573
}
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