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

facet-rs / facet / 19992174439

06 Dec 2025 05:56PM UTC coverage: 58.742% (-0.005%) from 58.747%
19992174439

Pull #1118

github

web-flow
Merge d1d251ac8 into 45a8cb1c3
Pull Request #1118: Reduce/cordon bloat in facet, introduce bloatbench

1138 of 3103 new or added lines in 61 files covered. (36.67%)

540 existing lines in 30 files now uncovered.

24225 of 41240 relevant lines covered (58.74%)

502.5 hits per line

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

74.26
/facet-core/src/impls_alloc/arc.rs
1
use core::ptr::NonNull;
2

3
use alloc::boxed::Box;
4
use alloc::sync::{Arc, Weak};
5
use alloc::vec::Vec;
6

7
use crate::shape_util::vtable_for_ptr;
8
use crate::{
9
    Def, Facet, KnownPointer, PointerDef, PointerFlags, PointerVTable, PtrConst, PtrMut, PtrUninit,
10
    Shape, ShapeBuilder, SliceBuilderVTable, TryBorrowInnerError, TryFromError, TryIntoInnerError,
11
    Type, UserType, ValueVTable,
12
};
13

14
unsafe impl<'a, T: Facet<'a>> Facet<'a> for Arc<T> {
15
    const SHAPE: &'static crate::Shape = &const {
16
        // Define the functions for transparent conversion between Arc<T> and T
17
        unsafe fn try_from<'a, 'src, 'dst, T: Facet<'a>>(
7✔
18
            src_ptr: PtrConst<'src>,
7✔
19
            src_shape: &'static Shape,
7✔
20
            dst: PtrUninit<'dst>,
7✔
21
        ) -> Result<PtrMut<'dst>, TryFromError> {
7✔
22
            if src_shape.id != T::SHAPE.id {
7✔
NEW
23
                return Err(TryFromError::UnsupportedSourceShape {
×
NEW
24
                    src_shape,
×
NEW
25
                    expected: &[T::SHAPE],
×
NEW
26
                });
×
27
            }
7✔
28
            let t = unsafe { src_ptr.read::<T>() };
7✔
29
            let arc = Arc::new(t);
7✔
30
            Ok(unsafe { dst.put(arc) })
7✔
31
        }
7✔
32

33
        unsafe fn try_into_inner<'a, 'src, 'dst, T: Facet<'a>>(
1✔
34
            src_ptr: PtrMut<'src>,
1✔
35
            dst: PtrUninit<'dst>,
1✔
36
        ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
1✔
37
            use alloc::sync::Arc;
38

39
            // Read the Arc from the source pointer
40
            let arc = unsafe { src_ptr.read::<Arc<T>>() };
1✔
41

42
            // Try to unwrap the Arc to get exclusive ownership
43
            match Arc::try_unwrap(arc) {
1✔
44
                Ok(inner) => Ok(unsafe { dst.put(inner) }),
1✔
NEW
45
                Err(arc) => {
×
46
                    // Arc is shared, so we can't extract the inner value
NEW
47
                    core::mem::forget(arc);
×
NEW
48
                    Err(TryIntoInnerError::Unavailable)
×
49
                }
50
            }
51
        }
1✔
52

NEW
53
        unsafe fn try_borrow_inner<'a, 'src, T: Facet<'a>>(
×
NEW
54
            src_ptr: PtrConst<'src>,
×
NEW
55
        ) -> Result<PtrConst<'src>, TryBorrowInnerError> {
×
NEW
56
            let arc = unsafe { src_ptr.get::<Arc<T>>() };
×
NEW
57
            Ok(PtrConst::new(NonNull::from(&**arc)))
×
NEW
58
        }
×
59

60
        ShapeBuilder::for_sized::<Self>(
NEW
61
            |f, opts| {
×
NEW
62
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
63
                if let Some(opts) = opts.for_children() {
×
NEW
64
                    write!(f, "<")?;
×
NEW
65
                    (T::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
66
                    write!(f, ">")?;
×
67
                } else {
NEW
68
                    write!(f, "<…>")?;
×
69
                }
NEW
70
                Ok(())
×
NEW
71
            },
×
72
            "Arc",
73
        )
74
        .vtable(ValueVTable {
75
            type_name: |f, opts| {
13✔
76
                write!(f, "{}", Self::SHAPE.type_identifier)?;
13✔
77
                if let Some(opts) = opts.for_children() {
13✔
78
                    write!(f, "<")?;
13✔
79
                    (T::SHAPE.vtable.type_name())(f, opts)?;
13✔
80
                    write!(f, ">")?;
13✔
81
                } else {
NEW
82
                    write!(f, "<…>")?;
×
83
                }
84
                Ok(())
13✔
85
            },
13✔
86
            try_from: Some(try_from::<T>),
87
            try_into_inner: Some(try_into_inner::<T>),
88
            try_borrow_inner: Some(try_borrow_inner::<T>),
89
            ..vtable_for_ptr::<T, Self>()
90
        })
91
        .ty(Type::User(UserType::Opaque))
92
        .def(Def::Pointer(PointerDef {
93
            vtable: &const {
94
                PointerVTable {
95
                    borrow_fn: Some(|this| {
10✔
96
                        let arc_ptr = unsafe { this.as_ptr::<Arc<T>>() };
10✔
97
                        let ptr = unsafe { &**arc_ptr };
10✔
98
                        PtrConst::new(NonNull::from(ptr))
10✔
99
                    }),
10✔
100
                    new_into_fn: Some(|this, ptr| {
13✔
101
                        let t = unsafe { ptr.read::<T>() };
13✔
102
                        let arc = Arc::new(t);
13✔
103
                        unsafe { this.put(arc) }
13✔
104
                    }),
13✔
105
                    downgrade_into_fn: Some(|strong, weak| unsafe {
106
                        weak.put(Arc::downgrade(strong.get::<Self>()))
2✔
107
                    }),
2✔
108
                    ..PointerVTable::new()
109
                }
110
            },
111
            pointee: Some(T::SHAPE),
112
            weak: Some(|| <Weak<T> as Facet>::SHAPE),
113
            strong: None,
114
            flags: PointerFlags::ATOMIC,
115
            known: Some(KnownPointer::Arc),
116
        }))
117
        .type_params(&[crate::TypeParam {
118
            name: "T",
119
            shape: T::SHAPE,
120
        }])
121
        .inner(T::SHAPE)
122
        .build()
123
    };
124
}
125

126
unsafe impl<'a> Facet<'a> for Arc<str> {
127
    const SHAPE: &'static crate::Shape = &const {
128
        ShapeBuilder::for_sized::<Self>(
NEW
129
            |f, opts| {
×
NEW
130
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
131
                if let Some(opts) = opts.for_children() {
×
NEW
132
                    write!(f, "<")?;
×
NEW
133
                    (str::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
134
                    write!(f, ">")?;
×
135
                } else {
NEW
136
                    write!(f, "<…>")?;
×
137
                }
NEW
138
                Ok(())
×
NEW
139
            },
×
140
            "Arc",
141
        )
142
        .vtable(ValueVTable {
143
            type_name: |f, opts| {
3✔
144
                write!(f, "{}", Self::SHAPE.type_identifier)?;
3✔
145
                if let Some(opts) = opts.for_children() {
3✔
146
                    write!(f, "<")?;
3✔
147
                    (str::SHAPE.vtable.type_name())(f, opts)?;
3✔
148
                    write!(f, ">")?;
3✔
149
                } else {
NEW
150
                    write!(f, "<…>")?;
×
151
                }
152
                Ok(())
3✔
153
            },
3✔
154
            ..vtable_for_ptr::<str, Self>()
155
        })
156
        .ty(Type::User(UserType::Opaque))
157
        .def(Def::Pointer(PointerDef {
158
            vtable: &const {
159
                PointerVTable {
160
                    borrow_fn: Some(|this| unsafe {
161
                        let concrete = this.get::<Arc<str>>();
1✔
162
                        let s: &str = concrete;
1✔
163
                        PtrConst::new(NonNull::from(s))
1✔
164
                    }),
1✔
165
                    downgrade_into_fn: Some(|strong, weak| unsafe {
NEW
166
                        weak.put(Arc::downgrade(strong.get::<Self>()))
×
NEW
167
                    }),
×
168
                    ..PointerVTable::new()
169
                }
170
            },
171
            pointee: Some(str::SHAPE),
172
            weak: Some(|| <Weak<str> as Facet>::SHAPE),
173
            strong: None,
174
            flags: PointerFlags::ATOMIC,
175
            known: Some(KnownPointer::Arc),
176
        }))
177
        .type_params(&[crate::TypeParam {
178
            name: "T",
179
            shape: str::SHAPE,
180
        }])
181
        .inner(str::SHAPE)
182
        .build()
183
    };
184
}
185

186
unsafe impl<'a, U: Facet<'a>> Facet<'a> for Arc<[U]> {
187
    const SHAPE: &'static crate::Shape = &const {
188
        fn slice_builder_new<'a, U: Facet<'a>>() -> PtrMut<'static> {
15✔
189
            let v = Box::new(Vec::<U>::new());
15✔
190
            let raw = Box::into_raw(v);
15✔
191
            PtrMut::new(unsafe { NonNull::new_unchecked(raw) })
15✔
192
        }
15✔
193

194
        fn slice_builder_push<'a, U: Facet<'a>>(builder: PtrMut, item: PtrMut) {
41✔
195
            unsafe {
41✔
196
                let vec = builder.as_mut::<Vec<U>>();
41✔
197
                let value = item.read::<U>();
41✔
198
                vec.push(value);
41✔
199
            }
41✔
200
        }
41✔
201

202
        fn slice_builder_convert<'a, U: Facet<'a>>(builder: PtrMut<'static>) -> PtrConst<'static> {
14✔
203
            unsafe {
204
                let vec_box = Box::from_raw(builder.as_ptr::<Vec<U>>() as *mut Vec<U>);
14✔
205
                let arc: Arc<[U]> = (*vec_box).into();
14✔
206
                let arc_box = Box::new(arc);
14✔
207
                PtrConst::new(NonNull::new_unchecked(Box::into_raw(arc_box)))
14✔
208
            }
209
        }
14✔
210

211
        fn slice_builder_free<'a, U: Facet<'a>>(builder: PtrMut<'static>) {
1✔
212
            unsafe {
1✔
213
                let _ = Box::from_raw(builder.as_ptr::<Vec<U>>() as *mut Vec<U>);
1✔
214
            }
1✔
215
        }
1✔
216

217
        ShapeBuilder::for_sized::<Self>(
NEW
218
            |f, opts| {
×
NEW
219
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
220
                if let Some(opts) = opts.for_children() {
×
NEW
221
                    write!(f, "<")?;
×
NEW
222
                    (<[U]>::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
223
                    write!(f, ">")?;
×
224
                } else {
NEW
225
                    write!(f, "<…>")?;
×
226
                }
NEW
227
                Ok(())
×
NEW
228
            },
×
229
            "Arc",
230
        )
231
        .vtable(ValueVTable {
232
            type_name: |f, opts| {
10✔
233
                write!(f, "{}", Self::SHAPE.type_identifier)?;
10✔
234
                if let Some(opts) = opts.for_children() {
10✔
235
                    write!(f, "<")?;
10✔
236
                    (<[U]>::SHAPE.vtable.type_name())(f, opts)?;
10✔
237
                    write!(f, ">")?;
10✔
238
                } else {
NEW
239
                    write!(f, "<…>")?;
×
240
                }
241
                Ok(())
10✔
242
            },
10✔
243
            ..vtable_for_ptr::<[U], Self>()
244
        })
245
        .ty(Type::User(UserType::Opaque))
246
        .def(Def::Pointer(PointerDef {
247
            vtable: &const {
248
                PointerVTable {
249
                    borrow_fn: Some(|this| unsafe {
250
                        let concrete = this.get::<Arc<[U]>>();
2✔
251
                        let s: &[U] = concrete;
2✔
252
                        PtrConst::new(NonNull::from(s))
2✔
253
                    }),
2✔
254
                    downgrade_into_fn: Some(|strong, weak| unsafe {
NEW
255
                        weak.put(Arc::downgrade(strong.get::<Self>()))
×
NEW
256
                    }),
×
257
                    slice_builder_vtable: Some(
258
                        &const {
259
                            SliceBuilderVTable::new(
260
                                slice_builder_new::<U>,
261
                                slice_builder_push::<U>,
262
                                slice_builder_convert::<U>,
263
                                slice_builder_free::<U>,
264
                            )
265
                        },
266
                    ),
267
                    ..PointerVTable::new()
268
                }
269
            },
270
            pointee: Some(<[U]>::SHAPE),
271
            weak: Some(|| <Weak<[U]> as Facet>::SHAPE),
272
            strong: None,
273
            flags: PointerFlags::ATOMIC,
274
            known: Some(KnownPointer::Arc),
275
        }))
276
        .type_params(&[crate::TypeParam {
277
            name: "T",
278
            shape: <[U]>::SHAPE,
279
        }])
280
        .inner(<[U]>::SHAPE)
281
        .build()
282
    };
283
}
284

285
unsafe impl<'a, T: Facet<'a>> Facet<'a> for Weak<T> {
286
    const SHAPE: &'static crate::Shape = &const {
287
        ShapeBuilder::for_sized::<Self>(
NEW
288
            |f, opts| {
×
NEW
289
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
290
                if let Some(opts) = opts.for_children() {
×
NEW
291
                    write!(f, "<")?;
×
NEW
292
                    (T::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
293
                    write!(f, ">")?;
×
294
                } else {
NEW
295
                    write!(f, "<…>")?;
×
296
                }
NEW
297
                Ok(())
×
NEW
298
            },
×
299
            "Weak",
300
        )
301
        .vtable({
NEW
302
            ValueVTable::builder(|f, opts| {
×
NEW
303
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
304
                if let Some(opts) = opts.for_children() {
×
NEW
305
                    write!(f, "<")?;
×
NEW
306
                    (T::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
307
                    write!(f, ">")?;
×
308
                } else {
NEW
309
                    write!(f, "<…>")?;
×
310
                }
NEW
311
                Ok(())
×
UNCOV
312
            })
×
313
            .drop_in_place(ValueVTable::drop_in_place_for::<alloc::sync::Weak<T>>())
NEW
314
            .default_in_place(|target| unsafe { target.put(alloc::sync::Weak::<T>::new()) })
×
NEW
315
            .clone_into(|src, dst| unsafe { dst.put(src.get::<alloc::sync::Weak<T>>().clone()) })
×
NEW
316
            .debug(|_this, f| write!(f, "(Weak)"))
×
317
            .build()
318
        })
319
        .ty(Type::User(UserType::Opaque))
320
        .def(Def::Pointer(PointerDef {
321
            vtable: &const {
322
                PointerVTable {
323
                    upgrade_into_fn: Some(|weak, strong| unsafe {
324
                        Some(strong.put(weak.get::<Self>().upgrade()?))
2✔
325
                    }),
2✔
326
                    ..PointerVTable::new()
327
                }
328
            },
329
            pointee: Some(T::SHAPE),
330
            weak: None,
331
            strong: Some(<Arc<T> as Facet>::SHAPE),
332
            flags: PointerFlags::ATOMIC.union(PointerFlags::WEAK),
333
            known: Some(KnownPointer::ArcWeak),
334
        }))
335
        .type_params(&[crate::TypeParam {
336
            name: "T",
337
            shape: T::SHAPE,
338
        }])
339
        .inner(T::SHAPE)
340
        .build()
341
    };
342
}
343

344
unsafe impl<'a> Facet<'a> for Weak<str> {
345
    const SHAPE: &'static crate::Shape = &const {
346
        ShapeBuilder::for_sized::<Self>(
NEW
347
            |f, opts| {
×
NEW
348
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
349
                if let Some(opts) = opts.for_children() {
×
NEW
350
                    write!(f, "<")?;
×
NEW
351
                    (str::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
352
                    write!(f, ">")?;
×
353
                } else {
NEW
354
                    write!(f, "<…>")?;
×
355
                }
NEW
356
                Ok(())
×
NEW
357
            },
×
358
            "Weak",
359
        )
360
        .vtable({
NEW
361
            ValueVTable::builder(|f, opts| {
×
NEW
362
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
363
                if let Some(opts) = opts.for_children() {
×
NEW
364
                    write!(f, "<")?;
×
NEW
365
                    (str::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
366
                    write!(f, ">")?;
×
367
                } else {
NEW
368
                    write!(f, "<…>")?;
×
369
                }
NEW
370
                Ok(())
×
UNCOV
371
            })
×
372
            .drop_in_place(ValueVTable::drop_in_place_for::<alloc::sync::Weak<str>>())
NEW
373
            .clone_into(|src, dst| unsafe { dst.put(src.get::<alloc::sync::Weak<str>>().clone()) })
×
NEW
374
            .debug(|_this, f| write!(f, "(Weak)"))
×
375
            .build()
376
        })
377
        .ty(Type::User(UserType::Opaque))
378
        .def(Def::Pointer(PointerDef {
379
            vtable: &const {
380
                PointerVTable {
381
                    upgrade_into_fn: Some(|weak, strong| unsafe {
NEW
382
                        Some(strong.put(weak.get::<Self>().upgrade()?))
×
NEW
383
                    }),
×
384
                    ..PointerVTable::new()
385
                }
386
            },
387
            pointee: Some(str::SHAPE),
388
            weak: None,
389
            strong: Some(<Arc<str> as Facet>::SHAPE),
390
            flags: PointerFlags::ATOMIC.union(PointerFlags::WEAK),
391
            known: Some(KnownPointer::ArcWeak),
392
        }))
393
        .type_params(&[crate::TypeParam {
394
            name: "T",
395
            shape: str::SHAPE,
396
        }])
397
        .inner(str::SHAPE)
398
        .build()
399
    };
400
}
401

402
unsafe impl<'a, U: Facet<'a>> Facet<'a> for Weak<[U]> {
403
    const SHAPE: &'static crate::Shape = &const {
404
        ShapeBuilder::for_sized::<Self>(
NEW
405
            |f, opts| {
×
NEW
406
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
407
                if let Some(opts) = opts.for_children() {
×
NEW
408
                    write!(f, "<")?;
×
NEW
409
                    (<[U]>::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
410
                    write!(f, ">")?;
×
411
                } else {
NEW
412
                    write!(f, "<…>")?;
×
413
                }
NEW
414
                Ok(())
×
NEW
415
            },
×
416
            "Weak",
417
        )
418
        .vtable({
NEW
419
            ValueVTable::builder(|f, opts| {
×
NEW
420
                write!(f, "{}", Self::SHAPE.type_identifier)?;
×
NEW
421
                if let Some(opts) = opts.for_children() {
×
NEW
422
                    write!(f, "<")?;
×
NEW
423
                    (<[U]>::SHAPE.vtable.type_name())(f, opts)?;
×
NEW
424
                    write!(f, ">")?;
×
425
                } else {
NEW
426
                    write!(f, "<…>")?;
×
427
                }
NEW
428
                Ok(())
×
UNCOV
429
            })
×
430
            .drop_in_place(ValueVTable::drop_in_place_for::<alloc::sync::Weak<[U]>>())
NEW
431
            .clone_into(|src, dst| unsafe { dst.put(src.get::<alloc::sync::Weak<[U]>>().clone()) })
×
NEW
432
            .debug(|_this, f| write!(f, "(Weak)"))
×
433
            .build()
434
        })
435
        .ty(Type::User(UserType::Opaque))
436
        .def(Def::Pointer(PointerDef {
437
            vtable: &const {
438
                PointerVTable {
439
                    upgrade_into_fn: Some(|weak, strong| unsafe {
NEW
440
                        Some(strong.put(weak.get::<Self>().upgrade()?))
×
NEW
441
                    }),
×
442
                    ..PointerVTable::new()
443
                }
444
            },
445
            pointee: Some(<[U]>::SHAPE),
446
            weak: None,
447
            strong: Some(<Arc<[U]> as Facet>::SHAPE),
448
            flags: PointerFlags::ATOMIC.union(PointerFlags::WEAK),
449
            known: Some(KnownPointer::ArcWeak),
450
        }))
451
        .type_params(&[crate::TypeParam {
452
            name: "T",
453
            shape: <[U]>::SHAPE,
454
        }])
455
        .inner(<[U]>::SHAPE)
456
        .build()
457
    };
458
}
459

460
#[cfg(test)]
461
mod tests {
462
    use core::mem::ManuallyDrop;
463

464
    use alloc::string::String;
465
    use alloc::sync::{Arc, Weak as ArcWeak};
466

467
    use super::*;
468

469
    #[test]
470
    fn test_arc_type_params() {
1✔
471
        let [type_param_1] = <Arc<i32>>::SHAPE.type_params else {
1✔
472
            panic!("Arc<T> should only have 1 type param")
×
473
        };
474
        assert_eq!(type_param_1.shape(), i32::SHAPE);
1✔
475
    }
1✔
476

477
    #[test]
478
    fn test_arc_vtable_1_new_borrow_drop() {
1✔
479
        facet_testhelpers::setup();
1✔
480

481
        let arc_shape = <Arc<String>>::SHAPE;
1✔
482
        let arc_def = arc_shape
1✔
483
            .def
1✔
484
            .into_pointer()
1✔
485
            .expect("Arc<T> should have a smart pointer definition");
1✔
486

487
        // Allocate memory for the Arc
488
        let arc_uninit_ptr = arc_shape.allocate().unwrap();
1✔
489

490
        // Get the function pointer for creating a new Arc from a value
491
        let new_into_fn = arc_def
1✔
492
            .vtable
1✔
493
            .new_into_fn
1✔
494
            .expect("Arc<T> should have new_into_fn");
1✔
495

496
        // Create the value and initialize the Arc
497
        let mut value = ManuallyDrop::new(String::from("example"));
1✔
498
        let arc_ptr =
1✔
499
            unsafe { new_into_fn(arc_uninit_ptr, PtrMut::new(NonNull::from(&mut value))) };
1✔
500
        // The value now belongs to the Arc, prevent its drop
501

502
        // Get the function pointer for borrowing the inner value
503
        let borrow_fn = arc_def
1✔
504
            .vtable
1✔
505
            .borrow_fn
1✔
506
            .expect("Arc<T> should have borrow_fn");
1✔
507

508
        // Borrow the inner value and check it
509
        let borrowed_ptr = unsafe { borrow_fn(arc_ptr.as_const()) };
1✔
510
        // SAFETY: borrowed_ptr points to a valid String within the Arc
511
        assert_eq!(unsafe { borrowed_ptr.get::<String>() }, "example");
1✔
512

513
        // Get the function pointer for dropping the Arc
514
        let drop_fn = arc_shape
1✔
515
            .vtable
1✔
516
            .drop_in_place
1✔
517
            .expect("Arc<T> should have drop_in_place");
1✔
518

519
        // Drop the Arc in place
520
        // SAFETY: arc_ptr points to a valid Arc<String>
521
        unsafe { drop_fn(arc_ptr) };
1✔
522

523
        // Deallocate the memory
524
        // SAFETY: arc_ptr was allocated by arc_shape and is now dropped (but memory is still valid)
525
        unsafe { arc_shape.deallocate_mut(arc_ptr).unwrap() };
1✔
526
    }
1✔
527

528
    #[test]
529
    fn test_arc_vtable_2_downgrade_upgrade_drop() {
1✔
530
        facet_testhelpers::setup();
1✔
531

532
        let arc_shape = <Arc<String>>::SHAPE;
1✔
533
        let arc_def = arc_shape
1✔
534
            .def
1✔
535
            .into_pointer()
1✔
536
            .expect("Arc<T> should have a smart pointer definition");
1✔
537

538
        let weak_shape = <ArcWeak<String>>::SHAPE;
1✔
539
        let weak_def = weak_shape
1✔
540
            .def
1✔
541
            .into_pointer()
1✔
542
            .expect("ArcWeak<T> should have a smart pointer definition");
1✔
543

544
        // 1. Create the first Arc (arc1)
545
        let arc1_uninit_ptr = arc_shape.allocate().unwrap();
1✔
546
        let new_into_fn = arc_def.vtable.new_into_fn.unwrap();
1✔
547
        let mut value = ManuallyDrop::new(String::from("example"));
1✔
548
        let arc1_ptr =
1✔
549
            unsafe { new_into_fn(arc1_uninit_ptr, PtrMut::new(NonNull::from(&mut value))) };
1✔
550

551
        // 2. Downgrade arc1 to create a weak pointer (weak1)
552
        let weak1_uninit_ptr = weak_shape.allocate().unwrap();
1✔
553
        let downgrade_into_fn = arc_def.vtable.downgrade_into_fn.unwrap();
1✔
554
        // SAFETY: arc1_ptr points to a valid Arc, weak1_uninit_ptr is allocated for a Weak
555
        let weak1_ptr = unsafe { downgrade_into_fn(arc1_ptr, weak1_uninit_ptr) };
1✔
556

557
        // 3. Upgrade weak1 to create a second Arc (arc2)
558
        let arc2_uninit_ptr = arc_shape.allocate().unwrap();
1✔
559
        let upgrade_into_fn = weak_def.vtable.upgrade_into_fn.unwrap();
1✔
560
        // SAFETY: weak1_ptr points to a valid Weak, arc2_uninit_ptr is allocated for an Arc.
561
        // Upgrade should succeed as arc1 still exists.
562
        let arc2_ptr = unsafe { upgrade_into_fn(weak1_ptr, arc2_uninit_ptr) }
1✔
563
            .expect("Upgrade should succeed while original Arc exists");
1✔
564

565
        // Check the content of the upgraded Arc
566
        let borrow_fn = arc_def.vtable.borrow_fn.unwrap();
1✔
567
        // SAFETY: arc2_ptr points to a valid Arc<String>
568
        let borrowed_ptr = unsafe { borrow_fn(arc2_ptr.as_const()) };
1✔
569
        // SAFETY: borrowed_ptr points to a valid String
570
        assert_eq!(unsafe { borrowed_ptr.get::<String>() }, "example");
1✔
571

572
        // 4. Drop everything and free memory
573
        let arc_drop_fn = arc_shape.vtable.drop_in_place.unwrap();
1✔
574
        let weak_drop_fn = weak_shape.vtable.drop_in_place.unwrap();
1✔
575

576
        unsafe {
1✔
577
            // Drop Arcs
1✔
578
            arc_drop_fn(arc1_ptr);
1✔
579
            arc_shape.deallocate_mut(arc1_ptr).unwrap();
1✔
580
            arc_drop_fn(arc2_ptr);
1✔
581
            arc_shape.deallocate_mut(arc2_ptr).unwrap();
1✔
582

1✔
583
            // Drop Weak
1✔
584
            weak_drop_fn(weak1_ptr);
1✔
585
            weak_shape.deallocate_mut(weak1_ptr).unwrap();
1✔
586
        }
1✔
587
    }
1✔
588

589
    #[test]
590
    fn test_arc_vtable_3_downgrade_drop_try_upgrade() {
1✔
591
        facet_testhelpers::setup();
1✔
592

593
        let arc_shape = <Arc<String>>::SHAPE;
1✔
594
        let arc_def = arc_shape
1✔
595
            .def
1✔
596
            .into_pointer()
1✔
597
            .expect("Arc<T> should have a smart pointer definition");
1✔
598

599
        let weak_shape = <ArcWeak<String>>::SHAPE;
1✔
600
        let weak_def = weak_shape
1✔
601
            .def
1✔
602
            .into_pointer()
1✔
603
            .expect("ArcWeak<T> should have a smart pointer definition");
1✔
604

605
        // 1. Create the strong Arc (arc1)
606
        let arc1_uninit_ptr = arc_shape.allocate().unwrap();
1✔
607
        let new_into_fn = arc_def.vtable.new_into_fn.unwrap();
1✔
608
        let mut value = ManuallyDrop::new(String::from("example"));
1✔
609
        let arc1_ptr =
1✔
610
            unsafe { new_into_fn(arc1_uninit_ptr, PtrMut::new(NonNull::from(&mut value))) };
1✔
611

612
        // 2. Downgrade arc1 to create a weak pointer (weak1)
613
        let weak1_uninit_ptr = weak_shape.allocate().unwrap();
1✔
614
        let downgrade_into_fn = arc_def.vtable.downgrade_into_fn.unwrap();
1✔
615
        // SAFETY: arc1_ptr is valid, weak1_uninit_ptr is allocated for Weak
616
        let weak1_ptr = unsafe { downgrade_into_fn(arc1_ptr, weak1_uninit_ptr) };
1✔
617

618
        // 3. Drop and free the strong pointer (arc1)
619
        let arc_drop_fn = arc_shape.vtable.drop_in_place.unwrap();
1✔
620
        unsafe {
1✔
621
            arc_drop_fn(arc1_ptr);
1✔
622
            arc_shape.deallocate_mut(arc1_ptr).unwrap();
1✔
623
        }
1✔
624

625
        // 4. Attempt to upgrade the weak pointer (weak1)
626
        let upgrade_into_fn = weak_def.vtable.upgrade_into_fn.unwrap();
1✔
627
        let arc2_uninit_ptr = arc_shape.allocate().unwrap();
1✔
628
        // SAFETY: weak1_ptr is valid (though points to dropped data), arc2_uninit_ptr is allocated for Arc
629
        let upgrade_result = unsafe { upgrade_into_fn(weak1_ptr, arc2_uninit_ptr) };
1✔
630

631
        // Assert that the upgrade failed
632
        assert!(
1✔
633
            upgrade_result.is_none(),
1✔
634
            "Upgrade should fail after the strong Arc is dropped"
635
        );
636

637
        // 5. Clean up: Deallocate the memory intended for the failed upgrade and drop/deallocate the weak pointer
638
        let weak_drop_fn = weak_shape.vtable.drop_in_place.unwrap();
1✔
639
        unsafe {
1✔
640
            // Deallocate the *uninitialized* memory allocated for the failed upgrade attempt
1✔
641
            arc_shape.deallocate_uninit(arc2_uninit_ptr).unwrap();
1✔
642

1✔
643
            // Drop and deallocate the weak pointer
1✔
644
            weak_drop_fn(weak1_ptr);
1✔
645
            weak_shape.deallocate_mut(weak1_ptr).unwrap();
1✔
646
        }
1✔
647
    }
1✔
648

649
    #[test]
650
    fn test_arc_vtable_4_try_from() {
1✔
651
        facet_testhelpers::setup();
1✔
652

653
        // Get the shapes we'll be working with
654
        let string_shape = <String>::SHAPE;
1✔
655
        let arc_shape = <Arc<String>>::SHAPE;
1✔
656
        let arc_def = arc_shape
1✔
657
            .def
1✔
658
            .into_pointer()
1✔
659
            .expect("Arc<T> should have a smart pointer definition");
1✔
660

661
        // 1. Create a String value
662
        let value = ManuallyDrop::new(String::from("try_from test"));
1✔
663
        let value_ptr = PtrConst::new(NonNull::from(&value));
1✔
664

665
        // 2. Allocate memory for the Arc<String>
666
        let arc_uninit_ptr = arc_shape.allocate().unwrap();
1✔
667

668
        // 3. Get the try_from function from the Arc<String> shape's ValueVTable
669
        let try_from_fn = arc_shape
1✔
670
            .vtable
1✔
671
            .try_from
1✔
672
            .expect("Arc<T> should have try_from");
1✔
673

674
        // 4. Try to convert String to Arc<String>
675
        let arc_ptr = unsafe { try_from_fn(value_ptr, string_shape, arc_uninit_ptr) }
1✔
676
            .expect("try_from should succeed");
1✔
677

678
        // 5. Borrow the inner value and verify it's correct
679
        let borrow_fn = arc_def
1✔
680
            .vtable
1✔
681
            .borrow_fn
1✔
682
            .expect("Arc<T> should have borrow_fn");
1✔
683
        let borrowed_ptr = unsafe { borrow_fn(arc_ptr.as_const()) };
1✔
684

685
        // SAFETY: borrowed_ptr points to a valid String within the Arc
686
        assert_eq!(unsafe { borrowed_ptr.get::<String>() }, "try_from test");
1✔
687

688
        // 6. Clean up
689
        let drop_fn = arc_shape
1✔
690
            .vtable
1✔
691
            .drop_in_place
1✔
692
            .expect("Arc<T> should have drop_in_place");
1✔
693

694
        unsafe {
1✔
695
            drop_fn(arc_ptr);
1✔
696
            arc_shape.deallocate_mut(arc_ptr).unwrap();
1✔
697
        }
1✔
698
    }
1✔
699

700
    #[test]
701
    fn test_arc_vtable_5_try_into_inner() {
1✔
702
        facet_testhelpers::setup();
1✔
703

704
        // Get the shapes we'll be working with
705
        let string_shape = <String>::SHAPE;
1✔
706
        let arc_shape = <Arc<String>>::SHAPE;
1✔
707
        let arc_def = arc_shape
1✔
708
            .def
1✔
709
            .into_pointer()
1✔
710
            .expect("Arc<T> should have a smart pointer definition");
1✔
711

712
        // 1. Create an Arc<String>
713
        let arc_uninit_ptr = arc_shape.allocate().unwrap();
1✔
714
        let new_into_fn = arc_def
1✔
715
            .vtable
1✔
716
            .new_into_fn
1✔
717
            .expect("Arc<T> should have new_into_fn");
1✔
718

719
        let mut value = ManuallyDrop::new(String::from("try_into_inner test"));
1✔
720
        let arc_ptr =
1✔
721
            unsafe { new_into_fn(arc_uninit_ptr, PtrMut::new(NonNull::from(&mut value))) };
1✔
722

723
        // 2. Allocate memory for the extracted String
724
        let string_uninit_ptr = string_shape.allocate().unwrap();
1✔
725

726
        // 3. Get the try_into_inner function from the Arc<String>'s ValueVTable
727
        let try_into_inner_fn = arc_shape
1✔
728
            .vtable
1✔
729
            .try_into_inner
1✔
730
            .expect("Arc<T> Shape should have try_into_inner");
1✔
731

732
        // 4. Try to extract the String from the Arc<String>
733
        // This should succeed because we have exclusive access to the Arc (strong count = 1)
734
        let string_ptr = unsafe { try_into_inner_fn(arc_ptr, string_uninit_ptr) }
1✔
735
            .expect("try_into_inner should succeed with exclusive access");
1✔
736

737
        // 5. Verify the extracted String
738
        assert_eq!(
1✔
739
            unsafe { string_ptr.as_const().get::<String>() },
1✔
740
            "try_into_inner test"
741
        );
742

743
        // 6. Clean up
744
        let string_drop_fn = string_shape
1✔
745
            .vtable
1✔
746
            .drop_in_place
1✔
747
            .expect("String should have drop_in_place");
1✔
748

749
        unsafe {
1✔
750
            // The Arc should already be dropped by try_into_inner
1✔
751
            // But we still need to deallocate its memory
1✔
752
            arc_shape.deallocate_mut(arc_ptr).unwrap();
1✔
753

1✔
754
            // Drop and deallocate the extracted String
1✔
755
            string_drop_fn(string_ptr);
1✔
756
            string_shape.deallocate_mut(string_ptr).unwrap();
1✔
757
        }
1✔
758
    }
1✔
759

760
    #[test]
761
    fn test_arc_vtable_6_slice_builder() {
1✔
762
        facet_testhelpers::setup();
1✔
763

764
        // Get the shapes we'll be working with
765
        let arc_slice_shape = <Arc<[i32]>>::SHAPE;
1✔
766
        let arc_slice_def = arc_slice_shape
1✔
767
            .def
1✔
768
            .into_pointer()
1✔
769
            .expect("Arc<[i32]> should have a smart pointer definition");
1✔
770

771
        // Get the slice builder vtable
772
        let slice_builder_vtable = arc_slice_def
1✔
773
            .vtable
1✔
774
            .slice_builder_vtable
1✔
775
            .expect("Arc<[i32]> should have slice_builder_vtable");
1✔
776

777
        // 1. Create a new builder
778
        let builder_ptr = (slice_builder_vtable.new_fn)();
1✔
779

780
        // 2. Push some items to the builder
781
        let push_fn = slice_builder_vtable.push_fn;
1✔
782
        let values = [1i32, 2, 3, 4, 5];
1✔
783
        for &value in &values {
5✔
784
            let mut value_copy = value;
5✔
785
            let value_ptr = PtrMut::new(NonNull::from(&mut value_copy));
5✔
786
            unsafe { push_fn(builder_ptr, value_ptr) };
5✔
787
        }
5✔
788

789
        // 3. Convert the builder to Arc<[i32]>
790
        let convert_fn = slice_builder_vtable.convert_fn;
1✔
791
        let arc_slice_ptr = unsafe { convert_fn(builder_ptr) };
1✔
792

793
        // 4. Verify the contents by borrowing
794
        let borrow_fn = arc_slice_def
1✔
795
            .vtable
1✔
796
            .borrow_fn
1✔
797
            .expect("Arc<[i32]> should have borrow_fn");
1✔
798
        let borrowed_ptr = unsafe { borrow_fn(arc_slice_ptr) };
1✔
799

800
        // Convert the wide pointer to a slice reference
801
        let slice = unsafe { borrowed_ptr.get::<[i32]>() };
1✔
802
        assert_eq!(slice, &[1, 2, 3, 4, 5]);
1✔
803

804
        // 5. Clean up - the Arc<[i32]> was boxed by convert_fn, we need to deallocate the Box
805
        unsafe {
1✔
806
            let _ = Box::from_raw(arc_slice_ptr.as_ptr::<Arc<[i32]>>() as *mut Arc<[i32]>);
1✔
807
        }
1✔
808
    }
1✔
809

810
    #[test]
811
    fn test_arc_vtable_7_slice_builder_free() {
1✔
812
        facet_testhelpers::setup();
1✔
813

814
        // Get the shapes we'll be working with
815
        let arc_slice_shape = <Arc<[String]>>::SHAPE;
1✔
816
        let arc_slice_def = arc_slice_shape
1✔
817
            .def
1✔
818
            .into_pointer()
1✔
819
            .expect("Arc<[String]> should have a smart pointer definition");
1✔
820

821
        // Get the slice builder vtable
822
        let slice_builder_vtable = arc_slice_def
1✔
823
            .vtable
1✔
824
            .slice_builder_vtable
1✔
825
            .expect("Arc<[String]> should have slice_builder_vtable");
1✔
826

827
        // 1. Create a new builder
828
        let builder_ptr = (slice_builder_vtable.new_fn)();
1✔
829

830
        // 2. Push some items to the builder
831
        let push_fn = slice_builder_vtable.push_fn;
1✔
832
        let strings = ["hello", "world", "test"];
1✔
833
        for &s in &strings {
3✔
834
            let mut value = ManuallyDrop::new(String::from(s));
3✔
835
            let value_ptr = PtrMut::new(NonNull::from(&mut value));
3✔
836
            unsafe { push_fn(builder_ptr, value_ptr) };
3✔
837
        }
3✔
838

839
        // 3. Instead of converting, test the free function
840
        // This simulates abandoning the builder without creating the Arc
841
        let free_fn = slice_builder_vtable.free_fn;
1✔
842
        unsafe { free_fn(builder_ptr) };
1✔
843

844
        // If we get here without panicking, the free worked correctly
845
    }
1✔
846
}
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