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

facet-rs / facet / 14669869436

25 Apr 2025 05:10PM UTC coverage: 57.77% (+0.03%) from 57.736%
14669869436

push

github

fasterthanlime
Merge value_vtable and value_vtable_inner

Closes #392

17 of 33 new or added lines in 8 files covered. (51.52%)

6602 of 11428 relevant lines covered (57.77%)

74.77 hits per line

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

79.87
/facet-core/src/impls_alloc/smartptr.rs
1
use core::alloc::Layout;
2

3
use crate::{
4
    ConstTypeId, Def, Facet, KnownSmartPointer, Opaque, PtrConst, PtrMut, PtrUninit, Shape,
5
    SmartPointerDef, SmartPointerFlags, SmartPointerVTable, TryBorrowInnerError, TryFromError,
6
    TryIntoInnerError, value_vtable,
7
};
8

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

28
        unsafe fn try_into_inner<'a, 'src, 'dst, T: Facet<'a>>(
×
29
            src_ptr: PtrConst<'src>,
×
30
            dst: PtrUninit<'dst>,
×
31
        ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
×
32
            let arc = unsafe { src_ptr.get::<alloc::sync::Arc<T>>() };
×
33
            match alloc::sync::Arc::try_unwrap(arc.clone()) {
×
34
                Ok(t) => Ok(unsafe { dst.put(t) }),
×
35
                Err(_) => Err(TryIntoInnerError::Unavailable),
×
36
            }
37
        }
×
38

39
        unsafe fn try_borrow_inner<'a, 'src, T: Facet<'a>>(
×
40
            src_ptr: PtrConst<'src>,
×
41
        ) -> Result<PtrConst<'src>, TryBorrowInnerError> {
×
42
            let arc = unsafe { src_ptr.get::<alloc::sync::Arc<T>>() };
×
43
            Ok(PtrConst::new(&**arc))
×
44
        }
×
45

46
        // Function to return inner type's shape
47
        fn inner_shape<'a, T: Facet<'a>>() -> &'static Shape {
2✔
48
            T::SHAPE
2✔
49
        }
2✔
50

51
        crate::Shape::builder()
52
            .id(ConstTypeId::of::<Self>())
53
            .layout(Layout::new::<Self>())
54
            .type_params(&[crate::TypeParam {
55
                name: "T",
56
                shape: || T::SHAPE,
2✔
57
            }])
58
            .def(Def::SmartPointer(
59
                SmartPointerDef::builder()
60
                    .pointee(T::SHAPE)
61
                    .flags(SmartPointerFlags::ATOMIC)
62
                    .known(KnownSmartPointer::Arc)
63
                    .weak(|| <alloc::sync::Weak<T> as Facet>::SHAPE)
×
64
                    .vtable(
65
                        &const {
66
                            SmartPointerVTable::builder()
67
                                .borrow_fn(|this| {
2✔
68
                                    let ptr = Self::as_ptr(unsafe { this.get() });
2✔
69
                                    PtrConst::new(ptr)
2✔
70
                                })
2✔
71
                                .new_into_fn(|this, ptr| {
1✔
72
                                    let t = unsafe { ptr.read::<T>() };
1✔
73
                                    let arc = alloc::sync::Arc::new(t);
1✔
74
                                    unsafe { this.put(arc) }
1✔
75
                                })
1✔
76
                                .downgrade_into_fn(|strong, weak| unsafe {
1✔
77
                                    weak.put(alloc::sync::Arc::downgrade(strong.get::<Self>()))
1✔
78
                                })
1✔
79
                                .build()
80
                        },
81
                    )
82
                    .build(),
83
            ))
84
            .vtable(
85
                &const {
86
                    let mut vtable =
NEW
87
                        value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(f, "Arc"));
×
88
                    vtable.try_from = Some(try_from::<T>);
89
                    vtable.try_into_inner = Some(try_into_inner::<T>);
90
                    vtable.try_borrow_inner = Some(try_borrow_inner::<T>);
91
                    vtable
92
                },
93
            )
94
            .inner(inner_shape::<T>)
95
            .build()
96
    };
97
}
98

99
unsafe impl<'a, T: Facet<'a>> Facet<'a> for alloc::sync::Weak<T> {
100
    const SHAPE: &'static crate::Shape = &const {
101
        // Function to return inner type's shape
102
        fn inner_shape<'a, T: Facet<'a>>() -> &'static Shape {
×
103
            T::SHAPE
×
104
        }
×
105

106
        crate::Shape::builder()
107
            .id(ConstTypeId::of::<Self>())
108
            .layout(Layout::new::<Self>())
109
            .type_params(&[crate::TypeParam {
110
                name: "T",
111
                shape: || T::SHAPE,
1✔
112
            }])
113
            .def(Def::SmartPointer(
114
                SmartPointerDef::builder()
115
                    .pointee(T::SHAPE)
116
                    .flags(SmartPointerFlags::ATOMIC.union(SmartPointerFlags::WEAK))
117
                    .known(KnownSmartPointer::ArcWeak)
118
                    .strong(|| <alloc::sync::Arc<T> as Facet>::SHAPE)
×
119
                    .vtable(
120
                        &const {
121
                            SmartPointerVTable::builder()
122
                                .upgrade_into_fn(|weak, strong| unsafe {
2✔
123
                                    Some(strong.put(weak.get::<Self>().upgrade()?))
2✔
124
                                })
2✔
125
                                .build()
126
                        },
127
                    )
128
                    .build(),
129
            ))
NEW
130
            .vtable(&const { value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(f, "Arc")) })
×
131
            .inner(inner_shape::<T>)
132
            .build()
133
    };
134
}
135

136
unsafe impl<'a, T: 'a> Facet<'a> for Opaque<alloc::sync::Arc<T>> {
137
    const SHAPE: &'static crate::Shape = &const {
138
        crate::Shape::builder()
139
            .id(ConstTypeId::of::<Self>())
140
            .layout(Layout::new::<Self>())
141
            .def(Def::SmartPointer(
142
                SmartPointerDef::builder()
143
                    .flags(SmartPointerFlags::ATOMIC)
144
                    .known(KnownSmartPointer::Arc)
145
                    .vtable(
146
                        &const {
147
                            SmartPointerVTable::builder()
148
                                .borrow_fn(|this| {
×
149
                                    let ptr = alloc::sync::Arc::<T>::as_ptr(unsafe { this.get() });
×
150
                                    PtrConst::new(ptr)
×
151
                                })
×
152
                                .new_into_fn(|this, ptr| {
×
153
                                    let t = unsafe { ptr.read::<T>() };
×
154
                                    let arc = alloc::sync::Arc::new(t);
×
155
                                    unsafe { this.put(arc) }
×
156
                                })
×
157
                                .build()
158
                        },
159
                    )
160
                    .build(),
161
            ))
162
            .vtable(&const { value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(f, "Arc")) })
1✔
163
            .build()
164
    };
165
}
166

167
unsafe impl<'a, T: Facet<'a>> Facet<'a> for alloc::rc::Rc<T> {
168
    const SHAPE: &'static crate::Shape = &const {
169
        // Define the functions for transparent conversion between Rc<T> and T
170
        unsafe fn try_from<'a, 'src, 'dst, T: Facet<'a>>(
×
171
            src_ptr: PtrConst<'src>,
×
172
            src_shape: &'static Shape,
×
173
            dst: PtrUninit<'dst>,
×
174
        ) -> Result<PtrMut<'dst>, TryFromError> {
×
175
            if src_shape.id != T::SHAPE.id {
×
176
                return Err(TryFromError::UnsupportedSourceShape {
×
177
                    src_shape,
×
178
                    expected: &[T::SHAPE],
×
179
                });
×
180
            }
×
181
            let t = unsafe { src_ptr.read::<T>() };
×
182
            let rc = alloc::rc::Rc::new(t);
×
183
            Ok(unsafe { dst.put(rc) })
×
184
        }
×
185

186
        unsafe fn try_into_inner<'a, 'src, 'dst, T: Facet<'a>>(
×
187
            src_ptr: PtrConst<'src>,
×
188
            dst: PtrUninit<'dst>,
×
189
        ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
×
190
            let rc = unsafe { src_ptr.get::<alloc::rc::Rc<T>>() };
×
191
            match alloc::rc::Rc::try_unwrap(rc.clone()) {
×
192
                Ok(t) => Ok(unsafe { dst.put(t) }),
×
193
                Err(_) => Err(TryIntoInnerError::Unavailable),
×
194
            }
195
        }
×
196

197
        unsafe fn try_borrow_inner<'a, 'src, T: Facet<'a>>(
×
198
            src_ptr: PtrConst<'src>,
×
199
        ) -> Result<PtrConst<'src>, TryBorrowInnerError> {
×
200
            let rc = unsafe { src_ptr.get::<alloc::rc::Rc<T>>() };
×
201
            Ok(PtrConst::new(&**rc))
×
202
        }
×
203

204
        // Function to return inner type's shape
205
        fn inner_shape<'a, T: Facet<'a>>() -> &'static Shape {
×
206
            T::SHAPE
×
207
        }
×
208

209
        crate::Shape::builder()
210
            .id(ConstTypeId::of::<Self>())
211
            .layout(Layout::new::<Self>())
212
            .type_params(&[crate::TypeParam {
213
                name: "T",
214
                shape: || T::SHAPE,
1✔
215
            }])
216
            .def(Def::SmartPointer(
217
                SmartPointerDef::builder()
218
                    .pointee(T::SHAPE)
219
                    .flags(SmartPointerFlags::EMPTY)
220
                    .known(KnownSmartPointer::Rc)
221
                    .weak(|| <alloc::rc::Weak<T> as Facet>::SHAPE)
×
222
                    .vtable(
223
                        &const {
224
                            SmartPointerVTable::builder()
225
                                .borrow_fn(|this| {
2✔
226
                                    let ptr = Self::as_ptr(unsafe { this.get() });
2✔
227
                                    PtrConst::new(ptr)
2✔
228
                                })
2✔
229
                                .new_into_fn(|this, ptr| {
1✔
230
                                    let t = unsafe { ptr.read::<T>() };
1✔
231
                                    let rc = alloc::rc::Rc::new(t);
1✔
232
                                    unsafe { this.put(rc) }
1✔
233
                                })
1✔
234
                                .downgrade_into_fn(|strong, weak| unsafe {
1✔
235
                                    weak.put(alloc::rc::Rc::downgrade(strong.get::<Self>()))
1✔
236
                                })
1✔
237
                                .build()
238
                        },
239
                    )
240
                    .build(),
241
            ))
242
            .vtable(
243
                &const {
NEW
244
                    let mut vtable = value_vtable!(alloc::rc::Rc<T>, |f, _opts| write!(f, "Rc"));
×
245
                    vtable.try_from = Some(try_from::<T>);
246
                    vtable.try_into_inner = Some(try_into_inner::<T>);
247
                    vtable.try_borrow_inner = Some(try_borrow_inner::<T>);
248
                    vtable
249
                },
250
            )
251
            .inner(inner_shape::<T>)
252
            .build()
253
    };
254
}
255

256
unsafe impl<'a, T: Facet<'a>> Facet<'a> for alloc::rc::Weak<T> {
257
    const SHAPE: &'static crate::Shape = &const {
258
        // Function to return inner type's shape
259
        fn inner_shape<'a, T: Facet<'a>>() -> &'static Shape {
×
260
            T::SHAPE
×
261
        }
×
262

263
        crate::Shape::builder()
264
            .id(ConstTypeId::of::<Self>())
265
            .layout(Layout::new::<Self>())
266
            .type_params(&[crate::TypeParam {
267
                name: "T",
268
                shape: || T::SHAPE,
×
269
            }])
270
            .def(Def::SmartPointer(
271
                SmartPointerDef::builder()
272
                    .pointee(T::SHAPE)
273
                    .flags(SmartPointerFlags::WEAK)
274
                    .known(KnownSmartPointer::RcWeak)
275
                    .strong(|| <alloc::rc::Rc<T> as Facet>::SHAPE)
×
276
                    .vtable(
277
                        &const {
278
                            SmartPointerVTable::builder()
279
                                .upgrade_into_fn(|weak, strong| unsafe {
2✔
280
                                    Some(strong.put(weak.get::<Self>().upgrade()?))
2✔
281
                                })
2✔
282
                                .build()
283
                        },
284
                    )
285
                    .build(),
286
            ))
NEW
287
            .vtable(&const { value_vtable!(alloc::rc::Rc<T>, |f, _opts| write!(f, "Rc")) })
×
288
            .inner(inner_shape::<T>)
289
            .build()
290
    };
291
}
292

293
unsafe impl<'a, T: 'a> Facet<'a> for Opaque<alloc::rc::Rc<T>> {
294
    const SHAPE: &'static crate::Shape = &const {
295
        crate::Shape::builder()
296
            .id(ConstTypeId::of::<Self>())
297
            .layout(Layout::new::<Self>())
298
            .def(Def::SmartPointer(
299
                SmartPointerDef::builder()
300
                    .known(KnownSmartPointer::Rc)
301
                    .vtable(
302
                        &const {
303
                            SmartPointerVTable::builder()
304
                                .borrow_fn(|this| {
×
305
                                    let ptr = alloc::rc::Rc::<T>::as_ptr(unsafe { this.get() });
×
306
                                    PtrConst::new(ptr)
×
307
                                })
×
308
                                .new_into_fn(|this, ptr| {
×
309
                                    let t = unsafe { ptr.read::<T>() };
×
310
                                    let rc = alloc::rc::Rc::new(t);
×
311
                                    unsafe { this.put(rc) }
×
312
                                })
×
313
                                .build()
314
                        },
315
                    )
316
                    .build(),
317
            ))
NEW
318
            .vtable(&const { value_vtable!(alloc::rc::Rc<T>, |f, _opts| write!(f, "Rc")) })
×
319
            .build()
320
    };
321
}
322

323
#[cfg(test)]
324
mod tests {
325
    use alloc::rc::{Rc, Weak as RcWeak};
326
    use alloc::string::String;
327
    use alloc::sync::{Arc, Weak as ArcWeak};
328
    use core::mem::MaybeUninit;
329

330
    use super::*;
331

332
    use crate::PtrUninit;
333

334
    #[test]
335
    fn test_arc_type_params() {
1✔
336
        let [type_param_1] = <Arc<i32>>::SHAPE.type_params else {
1✔
337
            panic!("Arc<T> should only have 1 type param")
×
338
        };
339
        assert_eq!(type_param_1.shape(), i32::SHAPE);
1✔
340
    }
1✔
341

342
    #[test]
343
    fn test_arc_vtable() {
1✔
344
        facet_testhelpers::setup();
1✔
345

1✔
346
        let arc_shape = <Arc<String>>::SHAPE;
1✔
347
        let arc_def = arc_shape
1✔
348
            .def
1✔
349
            .into_smart_pointer()
1✔
350
            .expect("Arc<T> should have a smart pointer definition");
1✔
351

1✔
352
        let weak_shape = <ArcWeak<String>>::SHAPE;
1✔
353
        let weak_def = weak_shape
1✔
354
            .def
1✔
355
            .into_smart_pointer()
1✔
356
            .expect("ArcWeak<T> should have a smart pointer definition");
1✔
357

1✔
358
        // Keep this alive as long as the Arc inside it is used
1✔
359
        let mut arc_storage = MaybeUninit::<Arc<String>>::zeroed();
1✔
360
        let arc_ptr = unsafe {
1✔
361
            let arc_uninit_ptr = PtrUninit::from_maybe_uninit(&mut arc_storage);
1✔
362

1✔
363
            let value = String::from("example");
1✔
364
            let value_ptr = PtrConst::new(&raw const value);
1✔
365

1✔
366
            // SAFETY:
1✔
367
            // - `arc_uninit_ptr` has layout Arc<String>
1✔
368
            // - `value_ptr` is String
1✔
369
            // - `value_ptr` is deallocated
1✔
370
            let returned_ptr = arc_def
1✔
371
                .vtable
1✔
372
                .new_into_fn
1✔
373
                .expect("Arc<T> should have new_into_fn vtable function")(
1✔
374
                arc_uninit_ptr,
1✔
375
                value_ptr,
1✔
376
            );
1✔
377

1✔
378
            // Don't run the destructor
1✔
379
            core::mem::forget(value);
1✔
380

1✔
381
            // Test correctness of the return value of new_into_fn
1✔
382
            // SAFETY: Using correct type Arc<String>
1✔
383
            assert_eq!(
1✔
384
                returned_ptr.as_ptr(),
1✔
385
                arc_uninit_ptr.as_byte_ptr() as *const Arc<String>
1✔
386
            );
387

388
            returned_ptr
1✔
389
        };
1✔
390

1✔
391
        unsafe {
1✔
392
            // SAFETY: `arc_ptr` is valid
1✔
393
            let borrowed = arc_def
1✔
394
                .vtable
1✔
395
                .borrow_fn
1✔
396
                .expect("Arc<T> should have borrow_fn vtable function")(
1✔
397
                arc_ptr.as_const()
1✔
398
            );
1✔
399
            assert_eq!(borrowed.get::<String>(), "example");
1✔
400
        }
401

402
        // Keep this alive as long as the RcWeak inside it is used
403
        let mut new_arc_storage = MaybeUninit::<ArcWeak<String>>::zeroed();
1✔
404
        let weak_ptr = unsafe {
1✔
405
            let weak_uninit_ptr = PtrUninit::from_maybe_uninit(&mut new_arc_storage);
1✔
406

1✔
407
            let returned_ptr = arc_def
1✔
408
                .vtable
1✔
409
                .downgrade_into_fn
1✔
410
                .expect("Arc<T> should have downgrade_into_fn vtable function")(
1✔
411
                arc_ptr,
1✔
412
                weak_uninit_ptr,
1✔
413
            );
1✔
414

1✔
415
            // Test correctness of the return value of downgrade_into_fn
1✔
416
            // SAFETY: Using correct type ArcWeak<String>
1✔
417
            assert_eq!(
1✔
418
                returned_ptr.as_ptr(),
1✔
419
                weak_uninit_ptr.as_byte_ptr() as *const ArcWeak<String>
1✔
420
            );
421

422
            returned_ptr
1✔
423
        };
1✔
424

1✔
425
        {
1✔
426
            let mut new_arc_storage = MaybeUninit::<Arc<String>>::zeroed();
1✔
427
            let new_arc_ptr = unsafe {
1✔
428
                let new_arc_uninit_ptr = PtrUninit::from_maybe_uninit(&mut new_arc_storage);
1✔
429

1✔
430
                // SAFETY: `weak_ptr` is valid and `new_arc_uninit_ptr` has layout Weak<String>
1✔
431
                let returned_ptr = weak_def
1✔
432
                    .vtable
1✔
433
                    .upgrade_into_fn
1✔
434
                    .expect("ArcWeak<T> should have upgrade_into_fn vtable function")(
1✔
435
                    weak_ptr,
1✔
436
                    new_arc_uninit_ptr,
1✔
437
                )
1✔
438
                .expect("Upgrade should be successful");
1✔
439

1✔
440
                // Test correctness of the return value of upgrade_into_fn
1✔
441
                // SAFETY: Using correct type Arc<String>
1✔
442
                assert_eq!(
1✔
443
                    returned_ptr.as_ptr(),
1✔
444
                    new_arc_uninit_ptr.as_byte_ptr() as *const Arc<String>
1✔
445
                );
446

447
                returned_ptr
1✔
448
            };
1✔
449

1✔
450
            unsafe {
1✔
451
                // SAFETY: `new_arc_ptr` is valid
1✔
452
                let borrowed = arc_def
1✔
453
                    .vtable
1✔
454
                    .borrow_fn
1✔
455
                    .expect("Arc<T> should have borrow_fn vtable function")(
1✔
456
                    new_arc_ptr.as_const()
1✔
457
                );
1✔
458
                assert_eq!(borrowed.get::<String>(), "example");
1✔
459
            }
460

461
            unsafe {
1✔
462
                // SAFETY: Proper value at `arc_ptr`, which is not accessed after this
1✔
463
                arc_shape
1✔
464
                    .vtable
1✔
465
                    .drop_in_place
1✔
466
                    .expect("Arc<T> should have drop_in_place vtable function")(
1✔
467
                    new_arc_ptr
1✔
468
                );
1✔
469
            }
1✔
470
        }
1✔
471

1✔
472
        unsafe {
1✔
473
            // SAFETY: Proper value at `arc_ptr`, which is not accessed after this
1✔
474
            arc_shape
1✔
475
                .vtable
1✔
476
                .drop_in_place
1✔
477
                .expect("Arc<T> should have drop_in_place vtable function")(arc_ptr);
1✔
478
        }
1✔
479

1✔
480
        unsafe {
1✔
481
            let mut new_arc_storage = MaybeUninit::<Arc<String>>::zeroed();
1✔
482
            let new_arc_uninit_ptr = PtrUninit::from_maybe_uninit(&mut new_arc_storage);
1✔
483

1✔
484
            // SAFETY: `weak_ptr` is valid and `new_arc_uninit_ptr` has layout Weak<String>
1✔
485
            if weak_def
1✔
486
                .vtable
1✔
487
                .upgrade_into_fn
1✔
488
                .expect("ArcWeak<T> should have upgrade_into_fn vtable function")(
1✔
489
                weak_ptr,
1✔
490
                new_arc_uninit_ptr,
1✔
491
            )
1✔
492
            .is_some()
1✔
493
            {
494
                panic!("Upgrade should be unsuccessful")
×
495
            }
1✔
496
        };
1✔
497

1✔
498
        unsafe {
1✔
499
            // SAFETY: Proper value at `weak_ptr`, which is not accessed after this
1✔
500
            weak_shape
1✔
501
                .vtable
1✔
502
                .drop_in_place
1✔
503
                .expect("ArcWeak<T> should have drop_in_place vtable function")(
1✔
504
                weak_ptr
1✔
505
            );
1✔
506
        }
1✔
507
    }
1✔
508

509
    #[test]
510
    fn test_rc_type_params() {
1✔
511
        let [type_param_1] = <Rc<i32>>::SHAPE.type_params else {
1✔
512
            panic!("Rc<T> should only have 1 type param")
×
513
        };
514
        assert_eq!(type_param_1.shape(), i32::SHAPE);
1✔
515
    }
1✔
516

517
    #[test]
518
    fn test_rc_vtable() {
1✔
519
        facet_testhelpers::setup();
1✔
520

1✔
521
        let rc_shape = <Rc<String>>::SHAPE;
1✔
522
        let rc_def = rc_shape
1✔
523
            .def
1✔
524
            .into_smart_pointer()
1✔
525
            .expect("Rc<T> should have a smart pointer definition");
1✔
526

1✔
527
        let weak_shape = <RcWeak<String>>::SHAPE;
1✔
528
        let weak_def = weak_shape
1✔
529
            .def
1✔
530
            .into_smart_pointer()
1✔
531
            .expect("RcWeak<T> should have a smart pointer definition");
1✔
532

1✔
533
        // Keep this alive as long as the Rc inside it is used
1✔
534
        let mut rc_storage = MaybeUninit::<Rc<String>>::zeroed();
1✔
535
        let rc_ptr = unsafe {
1✔
536
            let rc_uninit_ptr = PtrUninit::from_maybe_uninit(&mut rc_storage);
1✔
537

1✔
538
            let value = String::from("example");
1✔
539
            let value_ptr = PtrConst::new(&raw const value);
1✔
540

1✔
541
            // SAFETY:
1✔
542
            // - `rc_uninit_ptr` has layout Rc<String>
1✔
543
            // - `value_ptr` is String
1✔
544
            // - `value_ptr` is deallocated after this without running the destructor
1✔
545
            let returned_ptr = rc_def
1✔
546
                .vtable
1✔
547
                .new_into_fn
1✔
548
                .expect("Rc<T> should have new_into_fn vtable function")(
1✔
549
                rc_uninit_ptr, value_ptr
1✔
550
            );
1✔
551

1✔
552
            // Don't run the destructor
1✔
553
            core::mem::forget(value);
1✔
554

1✔
555
            // Test correctness of the return value of new_into_fn
1✔
556
            // SAFETY: Using correct type Rc<String>
1✔
557
            assert_eq!(
1✔
558
                returned_ptr.as_ptr(),
1✔
559
                rc_uninit_ptr.as_byte_ptr() as *const Rc<String>
1✔
560
            );
561

562
            returned_ptr
1✔
563
        };
1✔
564

1✔
565
        unsafe {
1✔
566
            // SAFETY: `rc_ptr` is valid
1✔
567
            let borrowed = rc_def
1✔
568
                .vtable
1✔
569
                .borrow_fn
1✔
570
                .expect("Rc<T> should have borrow_fn vtable function")(
1✔
571
                rc_ptr.as_const()
1✔
572
            );
1✔
573
            assert_eq!(borrowed.get::<String>(), "example");
1✔
574
        }
575

576
        // Keep this alive as long as the RcWeak inside it is used
577
        let mut new_rc_storage = MaybeUninit::<RcWeak<String>>::zeroed();
1✔
578
        let weak_ptr = unsafe {
1✔
579
            let weak_uninit_ptr = PtrUninit::from_maybe_uninit(&mut new_rc_storage);
1✔
580

1✔
581
            let returned_ptr = rc_def
1✔
582
                .vtable
1✔
583
                .downgrade_into_fn
1✔
584
                .expect("Rc<T> should have downgrade_into_fn vtable function")(
1✔
585
                rc_ptr,
1✔
586
                weak_uninit_ptr,
1✔
587
            );
1✔
588

1✔
589
            // Test correctness of the return value of downgrade_into_fn
1✔
590
            // SAFETY: Using correct type RcWeak<String>
1✔
591
            assert_eq!(
1✔
592
                returned_ptr.as_ptr(),
1✔
593
                weak_uninit_ptr.as_byte_ptr() as *const RcWeak<String>
1✔
594
            );
595

596
            returned_ptr
1✔
597
        };
1✔
598

1✔
599
        {
1✔
600
            let mut new_rc_storage = MaybeUninit::<Rc<String>>::zeroed();
1✔
601
            let new_rc_ptr = unsafe {
1✔
602
                let new_rc_uninit_ptr = PtrUninit::from_maybe_uninit(&mut new_rc_storage);
1✔
603

1✔
604
                // SAFETY: `weak_ptr` is valid and `new_rc_uninit_ptr` has layout Weak<String>
1✔
605
                let returned_ptr = weak_def
1✔
606
                    .vtable
1✔
607
                    .upgrade_into_fn
1✔
608
                    .expect("RcWeak<T> should have upgrade_into_fn vtable function")(
1✔
609
                    weak_ptr,
1✔
610
                    new_rc_uninit_ptr,
1✔
611
                )
1✔
612
                .expect("Upgrade should be successful");
1✔
613

1✔
614
                // Test correctness of the return value of upgrade_into_fn
1✔
615
                // SAFETY: Using correct type Rc<String>
1✔
616
                assert_eq!(
1✔
617
                    returned_ptr.as_ptr(),
1✔
618
                    new_rc_uninit_ptr.as_byte_ptr() as *const Rc<String>
1✔
619
                );
620

621
                returned_ptr
1✔
622
            };
1✔
623

1✔
624
            unsafe {
1✔
625
                // SAFETY: `new_rc_ptr` is valid
1✔
626
                let borrowed = rc_def
1✔
627
                    .vtable
1✔
628
                    .borrow_fn
1✔
629
                    .expect("Rc<T> should have borrow_fn vtable function")(
1✔
630
                    new_rc_ptr.as_const()
1✔
631
                );
1✔
632
                assert_eq!(borrowed.get::<String>(), "example");
1✔
633
            }
634

635
            unsafe {
1✔
636
                // SAFETY: Proper value at `rc_ptr`, which is not accessed after this
1✔
637
                rc_shape
1✔
638
                    .vtable
1✔
639
                    .drop_in_place
1✔
640
                    .expect("Rc<T> should have drop_in_place vtable function")(
1✔
641
                    new_rc_ptr
1✔
642
                );
1✔
643
            }
1✔
644
        }
1✔
645

1✔
646
        unsafe {
1✔
647
            // SAFETY: Proper value at `rc_ptr`, which is not accessed after this
1✔
648
            rc_shape
1✔
649
                .vtable
1✔
650
                .drop_in_place
1✔
651
                .expect("Rc<T> should have drop_in_place vtable function")(rc_ptr);
1✔
652
        }
1✔
653

1✔
654
        unsafe {
1✔
655
            let mut new_rc_storage = MaybeUninit::<Rc<String>>::zeroed();
1✔
656
            let new_rc_uninit_ptr = PtrUninit::from_maybe_uninit(&mut new_rc_storage);
1✔
657

1✔
658
            // SAFETY: `weak_ptr` is valid and `new_rc_uninit_ptr` has layout Weak<String>
1✔
659
            if weak_def
1✔
660
                .vtable
1✔
661
                .upgrade_into_fn
1✔
662
                .expect("RcWeak<T> should have upgrade_into_fn vtable function")(
1✔
663
                weak_ptr,
1✔
664
                new_rc_uninit_ptr,
1✔
665
            )
1✔
666
            .is_some()
1✔
667
            {
668
                panic!("Upgrade should be unsuccessful")
×
669
            }
1✔
670
        };
1✔
671

1✔
672
        unsafe {
1✔
673
            // SAFETY: Proper value at `weak_ptr`, which is not accessed after this
1✔
674
            weak_shape
1✔
675
                .vtable
1✔
676
                .drop_in_place
1✔
677
                .expect("RcWeak<T> should have drop_in_place vtable function")(weak_ptr);
1✔
678
        }
1✔
679
    }
1✔
680
}
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