• 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

53.2
/facet-core/src/impls_alloc/rc.rs
1
use core::ptr::NonNull;
2

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

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

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

34
                unsafe fn try_into_inner<'a, 'src, 'dst, T: Facet<'a>>(
×
35
                    src_ptr: PtrMut<'src>,
×
36
                    dst: PtrUninit<'dst>,
×
37
                ) -> Result<PtrMut<'dst>, TryIntoInnerError> {
×
38
                    let rc = unsafe { src_ptr.get::<Rc<T>>() };
×
39
                    match Rc::try_unwrap(rc.clone()) {
×
40
                        Ok(t) => Ok(unsafe { dst.put(t) }),
×
41
                        Err(_) => Err(TryIntoInnerError::Unavailable),
×
42
                    }
43
                }
×
44

45
                unsafe fn try_borrow_inner<'a, 'src, T: Facet<'a>>(
×
46
                    src_ptr: PtrConst<'src>,
×
47
                ) -> Result<PtrConst<'src>, TryBorrowInnerError> {
×
48
                    let rc = unsafe { src_ptr.get::<Rc<T>>() };
×
49
                    Ok(PtrConst::new(NonNull::from(&**rc)))
×
50
                }
×
51

52
                let mut vtable = value_vtable!(alloc::rc::Rc<T>, |f, opts| {
×
53
                    write!(f, "{}", Self::SHAPE.type_identifier)?;
×
54
                    if let Some(opts) = opts.for_children() {
×
55
                        write!(f, "<")?;
×
56
                        T::SHAPE.vtable.type_name()(f, opts)?;
×
57
                        write!(f, ">")?;
×
58
                    } else {
59
                        write!(f, "<…>")?;
×
60
                    }
61
                    Ok(())
×
62
                });
×
63
                {
64
                    vtable.try_from = Some(try_from::<T>);
65
                    vtable.try_into_inner = Some(try_into_inner::<T>);
66
                    vtable.try_borrow_inner = Some(try_borrow_inner::<T>);
67
                }
68
                vtable
69
            })
70
            .type_identifier("Rc")
71
            .type_params(&[crate::TypeParam {
72
                name: "T",
73
                shape: T::SHAPE,
74
            }])
75
            .ty(Type::User(UserType::Opaque))
76
            .def(Def::Pointer(
77
                PointerDef::builder()
78
                    .pointee(T::SHAPE)
79
                    .flags(PointerFlags::EMPTY)
80
                    .known(KnownPointer::Rc)
81
                    .weak(|| <Weak<T> as Facet>::SHAPE)
82
                    .vtable(
83
                        &const {
84
                            PointerVTable::builder()
85
                                .borrow_fn(|this| {
2✔
86
                                    let ptr = Self::as_ptr(unsafe { this.get() });
2✔
87
                                    PtrConst::new(unsafe { NonNull::new_unchecked(ptr as *mut T) })
2✔
88
                                })
2✔
89
                                .new_into_fn(|this, ptr| {
3✔
90
                                    let t = unsafe { ptr.read::<T>() };
3✔
91
                                    let rc = Rc::new(t);
3✔
92
                                    unsafe { this.put(rc) }
3✔
93
                                })
3✔
94
                                .downgrade_into_fn(|strong, weak| unsafe {
95
                                    weak.put(Rc::downgrade(strong.get::<Self>()))
2✔
96
                                })
2✔
97
                                .build()
98
                        },
99
                    )
100
                    .build(),
101
            ))
102
            .inner(T::SHAPE)
103
            .build()
104
    };
105
}
106

107
unsafe impl<'a> Facet<'a> for Rc<str> {
108
    const SHAPE: &'static crate::Shape = &const {
109
        crate::Shape::builder_for_sized::<Self>()
110
            .vtable({
111
                value_vtable!(alloc::rc::Rc<str>, |f, opts| {
×
112
                    write!(f, "{}", Self::SHAPE.type_identifier)?;
×
113
                    if let Some(opts) = opts.for_children() {
×
114
                        write!(f, "<")?;
×
115
                        (str::SHAPE.vtable.type_name())(f, opts)?;
×
116
                        write!(f, ">")?;
×
117
                    } else {
118
                        write!(f, "<…>")?;
×
119
                    }
120
                    Ok(())
×
121
                })
×
122
            })
123
            .type_identifier("Rc")
124
            .type_params(&[crate::TypeParam {
125
                name: "T",
126
                shape: str::SHAPE,
127
            }])
128
            .ty(Type::User(UserType::Opaque))
129
            .def(Def::Pointer(
130
                PointerDef::builder()
131
                    .pointee(str::SHAPE)
132
                    .flags(PointerFlags::EMPTY)
133
                    .known(KnownPointer::Rc)
134
                    .weak(|| <Weak<str> as Facet>::SHAPE)
135
                    .vtable(
136
                        &const {
137
                            PointerVTable::builder()
138
                                .borrow_fn(|this| unsafe {
139
                                    let concrete = this.get::<Rc<str>>();
×
140
                                    let s: &str = concrete;
×
141
                                    PtrConst::new(NonNull::from(s))
×
142
                                })
×
143
                                .downgrade_into_fn(|strong, weak| unsafe {
144
                                    weak.put(Rc::downgrade(strong.get::<Self>()))
×
145
                                })
×
146
                                .build()
147
                        },
148
                    )
149
                    .build(),
150
            ))
151
            .inner(str::SHAPE)
152
            .build()
153
    };
154
}
155

156
unsafe impl<'a, U: Facet<'a>> Facet<'a> for Rc<[U]> {
157
    const SHAPE: &'static crate::Shape = &const {
UNCOV
158
        fn slice_builder_new<'a, U: Facet<'a>>() -> PtrMut<'static> {
×
159
            let v = Box::new(Vec::<U>::new());
×
160
            let raw = Box::into_raw(v);
×
161
            PtrMut::new(unsafe { NonNull::new_unchecked(raw) })
×
162
        }
×
163

164
        fn slice_builder_push<'a, U: Facet<'a>>(builder: PtrMut, item: PtrMut) {
×
165
            unsafe {
×
166
                let vec = builder.as_mut::<Vec<U>>();
×
167
                let value = item.read::<U>();
×
168
                vec.push(value);
×
169
            }
×
170
        }
×
171

172
        fn slice_builder_convert<'a, U: Facet<'a>>(builder: PtrMut<'static>) -> PtrConst<'static> {
×
173
            unsafe {
174
                let vec_box = Box::from_raw(builder.as_ptr::<Vec<U>>() as *mut Vec<U>);
×
175
                let arc: Rc<[U]> = (*vec_box).into();
×
176
                let arc_box = Box::new(arc);
×
177
                PtrConst::new(NonNull::new_unchecked(Box::into_raw(arc_box)))
×
178
            }
179
        }
×
180

181
        fn slice_builder_free<'a, U: Facet<'a>>(builder: PtrMut<'static>) {
×
182
            unsafe {
×
183
                let _ = Box::from_raw(builder.as_ptr::<Vec<U>>() as *mut Vec<U>);
×
184
            }
×
185
        }
×
186

187
        crate::Shape::builder_for_sized::<Self>()
188
            .vtable({
189
                value_vtable!(alloc::rc::Rc<[U]>, |f, opts| {
×
190
                    write!(f, "{}", Self::SHAPE.type_identifier)?;
×
191
                    if let Some(opts) = opts.for_children() {
×
192
                        write!(f, "<")?;
×
193
                        (<[U]>::SHAPE.vtable.type_name())(f, opts)?;
×
194
                        write!(f, ">")?;
×
195
                    } else {
196
                        write!(f, "<…>")?;
×
197
                    }
198
                    Ok(())
×
199
                })
×
200
            })
201
            .type_identifier("Rc")
202
            .type_params(&[crate::TypeParam {
203
                name: "T",
204
                shape: <[U]>::SHAPE,
205
            }])
206
            .ty(Type::User(UserType::Opaque))
207
            .def(Def::Pointer(
208
                PointerDef::builder()
209
                    .pointee(<[U]>::SHAPE)
210
                    .flags(PointerFlags::EMPTY)
211
                    .known(KnownPointer::Rc)
212
                    .weak(|| <Weak<[U]> as Facet>::SHAPE)
213
                    .vtable(
214
                        &const {
215
                            PointerVTable::builder()
216
                                .borrow_fn(|this| unsafe {
217
                                    let concrete = this.get::<Rc<[U]>>();
×
218
                                    let s: &[U] = concrete;
×
219
                                    PtrConst::new(NonNull::from(s))
×
220
                                })
×
221
                                .downgrade_into_fn(|strong, weak| unsafe {
222
                                    weak.put(Rc::downgrade(strong.get::<Self>()))
×
223
                                })
×
224
                                .slice_builder_vtable(
225
                                    &const {
226
                                        SliceBuilderVTable::builder()
227
                                            .new_fn(slice_builder_new::<U>)
228
                                            .push_fn(slice_builder_push::<U>)
229
                                            .convert_fn(slice_builder_convert::<U>)
230
                                            .free_fn(slice_builder_free::<U>)
231
                                            .build()
232
                                    },
233
                                )
234
                                .build()
235
                        },
236
                    )
237
                    .build(),
238
            ))
239
            .inner(<[U]>::SHAPE)
240
            .build()
241
    };
242
}
243

244
unsafe impl<'a, T: Facet<'a>> Facet<'a> for Weak<T> {
245
    const SHAPE: &'static crate::Shape = &const {
246
        crate::Shape::builder_for_sized::<Self>()
247
            .vtable({
248
                value_vtable!(alloc::rc::Weak<T>, |f, opts| {
10✔
249
                    write!(f, "{}", Self::SHAPE.type_identifier)?;
10✔
250
                    if let Some(opts) = opts.for_children() {
10✔
251
                        write!(f, "<")?;
10✔
252
                        T::SHAPE.vtable.type_name()(f, opts)?;
10✔
253
                        write!(f, ">")?;
10✔
254
                    } else {
255
                        write!(f, "<…>")?;
×
256
                    }
257
                    Ok(())
10✔
258
                })
10✔
259
            })
260
            .type_identifier("Weak")
261
            .type_params(&[crate::TypeParam {
262
                name: "T",
263
                shape: T::SHAPE,
264
            }])
265
            .ty(Type::User(UserType::Opaque))
266
            .def(Def::Pointer(
267
                PointerDef::builder()
268
                    .pointee(T::SHAPE)
269
                    .flags(PointerFlags::WEAK)
270
                    .known(KnownPointer::RcWeak)
271
                    .strong(<Rc<T> as Facet>::SHAPE)
272
                    .vtable(
273
                        &const {
274
                            PointerVTable::builder()
275
                                .upgrade_into_fn(|weak, strong| unsafe {
276
                                    Some(strong.put(weak.get::<Self>().upgrade()?))
2✔
277
                                })
2✔
278
                                .build()
279
                        },
280
                    )
281
                    .build(),
282
            ))
283
            .inner(T::SHAPE)
284
            .build()
285
    };
286
}
287

288
unsafe impl<'a> Facet<'a> for Weak<str> {
289
    const SHAPE: &'static crate::Shape = &const {
290
        crate::Shape::builder_for_sized::<Self>()
291
            .vtable({
292
                value_vtable!(alloc::rc::Weak<str>, |f, opts| {
×
293
                    write!(f, "{}", Self::SHAPE.type_identifier)?;
×
294
                    if let Some(opts) = opts.for_children() {
×
295
                        write!(f, "<")?;
×
296
                        (str::SHAPE.vtable.type_name())(f, opts)?;
×
297
                        write!(f, ">")?;
×
298
                    } else {
299
                        write!(f, "<…>")?;
×
300
                    }
301
                    Ok(())
×
302
                })
×
303
            })
304
            .type_identifier("Weak")
305
            .type_params(&[crate::TypeParam {
306
                name: "T",
307
                shape: str::SHAPE,
308
            }])
309
            .ty(Type::User(UserType::Opaque))
310
            .def(Def::Pointer(
311
                PointerDef::builder()
312
                    .pointee(str::SHAPE)
313
                    .flags(PointerFlags::WEAK)
314
                    .known(KnownPointer::RcWeak)
315
                    .strong(<Rc<str> as Facet>::SHAPE)
316
                    .vtable(
317
                        &const {
318
                            PointerVTable::builder()
319
                                .upgrade_into_fn(|weak, strong| unsafe {
320
                                    Some(strong.put(weak.get::<Self>().upgrade()?))
×
321
                                })
×
322
                                .build()
323
                        },
324
                    )
325
                    .build(),
326
            ))
327
            .inner(str::SHAPE)
328
            .build()
329
    };
330
}
331

332
unsafe impl<'a, U: Facet<'a>> Facet<'a> for Weak<[U]> {
333
    const SHAPE: &'static crate::Shape = &const {
334
        crate::Shape::builder_for_sized::<Self>()
335
            .vtable({
336
                value_vtable!(alloc::rc::Weak<[U]>, |f, opts| {
×
337
                    write!(f, "{}", Self::SHAPE.type_identifier)?;
×
338
                    if let Some(opts) = opts.for_children() {
×
339
                        write!(f, "<")?;
×
340
                        (<[U]>::SHAPE.vtable.type_name())(f, opts)?;
×
341
                        write!(f, ">")?;
×
342
                    } else {
343
                        write!(f, "<…>")?;
×
344
                    }
345
                    Ok(())
×
346
                })
×
347
            })
348
            .type_identifier("Weak")
349
            .type_params(&[crate::TypeParam {
350
                name: "T",
351
                shape: <[U]>::SHAPE,
352
            }])
353
            .ty(Type::User(UserType::Opaque))
354
            .def(Def::Pointer(
355
                PointerDef::builder()
356
                    .pointee(<[U]>::SHAPE)
357
                    .flags(PointerFlags::WEAK)
358
                    .known(KnownPointer::RcWeak)
359
                    .strong(<Rc<[U]> as Facet>::SHAPE)
360
                    .vtable(
361
                        &const {
362
                            PointerVTable::builder()
363
                                .upgrade_into_fn(|weak, strong| unsafe {
364
                                    Some(strong.put(weak.get::<Self>().upgrade()?))
×
365
                                })
×
366
                                .build()
367
                        },
368
                    )
369
                    .build(),
370
            ))
371
            .inner(<[U]>::SHAPE)
372
            .build()
373
    };
374
}
375

376
#[cfg(test)]
377
mod tests {
378
    use core::mem::ManuallyDrop;
379

380
    use alloc::rc::{Rc, Weak as RcWeak};
381
    use alloc::string::String;
382

383
    use super::*;
384

385
    #[test]
386
    fn test_rc_type_params() {
1✔
387
        let [type_param_1] = <Rc<i32>>::SHAPE.type_params else {
1✔
388
            panic!("Rc<T> should only have 1 type param")
×
389
        };
390
        assert_eq!(type_param_1.shape(), i32::SHAPE);
1✔
391
    }
1✔
392

393
    #[test]
394
    fn test_rc_vtable_1_new_borrow_drop() {
1✔
395
        facet_testhelpers::setup();
1✔
396

397
        let rc_shape = <Rc<String>>::SHAPE;
1✔
398
        let rc_def = rc_shape
1✔
399
            .def
1✔
400
            .into_pointer()
1✔
401
            .expect("Rc<T> should have a smart pointer definition");
1✔
402

403
        // Allocate memory for the Rc
404
        let rc_uninit_ptr = rc_shape.allocate().unwrap();
1✔
405

406
        // Get the function pointer for creating a new Rc from a value
407
        let new_into_fn = rc_def
1✔
408
            .vtable
1✔
409
            .new_into_fn
1✔
410
            .expect("Rc<T> should have new_into_fn");
1✔
411

412
        // Create the value and initialize the Rc
413
        let mut value = ManuallyDrop::new(String::from("example"));
1✔
414
        let rc_ptr = unsafe { new_into_fn(rc_uninit_ptr, PtrMut::new(NonNull::from(&mut value))) };
1✔
415

416
        // Get the function pointer for borrowing the inner value
417
        let borrow_fn = rc_def
1✔
418
            .vtable
1✔
419
            .borrow_fn
1✔
420
            .expect("Rc<T> should have borrow_fn");
1✔
421

422
        // Borrow the inner value and check it
423
        let borrowed_ptr = unsafe { borrow_fn(rc_ptr.as_const()) };
1✔
424
        // SAFETY: borrowed_ptr points to a valid String within the Rc
425
        assert_eq!(unsafe { borrowed_ptr.get::<String>() }, "example");
1✔
426

427
        // Get the function pointer for dropping the Rc
428
        let drop_fn = rc_shape
1✔
429
            .vtable
1✔
430
            .drop_in_place
1✔
431
            .expect("Rc<T> should have drop_in_place");
1✔
432

433
        // Drop the Rc in place
434
        // SAFETY: rc_ptr points to a valid Rc<String>
435
        unsafe { drop_fn(rc_ptr) };
1✔
436

437
        // Deallocate the memory
438
        // SAFETY: rc_ptr was allocated by rc_shape and is now dropped (but memory is still valid)
439
        unsafe { rc_shape.deallocate_mut(rc_ptr).unwrap() };
1✔
440
    }
1✔
441

442
    #[test]
443
    fn test_rc_vtable_2_downgrade_upgrade_drop() {
1✔
444
        facet_testhelpers::setup();
1✔
445

446
        let rc_shape = <Rc<String>>::SHAPE;
1✔
447
        let rc_def = rc_shape
1✔
448
            .def
1✔
449
            .into_pointer()
1✔
450
            .expect("Rc<T> should have a smart pointer definition");
1✔
451

452
        let weak_shape = <RcWeak<String>>::SHAPE;
1✔
453
        let weak_def = weak_shape
1✔
454
            .def
1✔
455
            .into_pointer()
1✔
456
            .expect("RcWeak<T> should have a smart pointer definition");
1✔
457

458
        // 1. Create the first Rc (rc1)
459
        let rc1_uninit_ptr = rc_shape.allocate().unwrap();
1✔
460
        let new_into_fn = rc_def.vtable.new_into_fn.unwrap();
1✔
461
        let mut value = ManuallyDrop::new(String::from("example"));
1✔
462
        let rc1_ptr =
1✔
463
            unsafe { new_into_fn(rc1_uninit_ptr, PtrMut::new(NonNull::from(&mut value))) };
1✔
464

465
        // 2. Downgrade rc1 to create a weak pointer (weak1)
466
        let weak1_uninit_ptr = weak_shape.allocate().unwrap();
1✔
467
        let downgrade_into_fn = rc_def.vtable.downgrade_into_fn.unwrap();
1✔
468
        // SAFETY: rc1_ptr points to a valid Rc, weak1_uninit_ptr is allocated for a Weak
469
        let weak1_ptr = unsafe { downgrade_into_fn(rc1_ptr, weak1_uninit_ptr) };
1✔
470

471
        // 3. Upgrade weak1 to create a second Rc (rc2)
472
        let rc2_uninit_ptr = rc_shape.allocate().unwrap();
1✔
473
        let upgrade_into_fn = weak_def.vtable.upgrade_into_fn.unwrap();
1✔
474
        // SAFETY: weak1_ptr points to a valid Weak, rc2_uninit_ptr is allocated for an Rc.
475
        // Upgrade should succeed as rc1 still exists.
476
        let rc2_ptr = unsafe { upgrade_into_fn(weak1_ptr, rc2_uninit_ptr) }
1✔
477
            .expect("Upgrade should succeed while original Rc exists");
1✔
478

479
        // Check the content of the upgraded Rc
480
        let borrow_fn = rc_def.vtable.borrow_fn.unwrap();
1✔
481
        // SAFETY: rc2_ptr points to a valid Rc<String>
482
        let borrowed_ptr = unsafe { borrow_fn(rc2_ptr.as_const()) };
1✔
483
        // SAFETY: borrowed_ptr points to a valid String
484
        assert_eq!(unsafe { borrowed_ptr.get::<String>() }, "example");
1✔
485

486
        // 4. Drop everything and free memory
487
        let rc_drop_fn = rc_shape.vtable.drop_in_place.unwrap();
1✔
488
        let weak_drop_fn = weak_shape.vtable.drop_in_place.unwrap();
1✔
489

490
        unsafe {
1✔
491
            // Drop Rcs
1✔
492
            rc_drop_fn(rc1_ptr);
1✔
493
            rc_shape.deallocate_mut(rc1_ptr).unwrap();
1✔
494
            rc_drop_fn(rc2_ptr);
1✔
495
            rc_shape.deallocate_mut(rc2_ptr).unwrap();
1✔
496

1✔
497
            // Drop Weak
1✔
498
            weak_drop_fn(weak1_ptr);
1✔
499
            weak_shape.deallocate_mut(weak1_ptr).unwrap();
1✔
500
        }
1✔
501
    }
1✔
502

503
    #[test]
504
    fn test_rc_vtable_3_downgrade_drop_try_upgrade() {
1✔
505
        facet_testhelpers::setup();
1✔
506

507
        let rc_shape = <Rc<String>>::SHAPE;
1✔
508
        let rc_def = rc_shape
1✔
509
            .def
1✔
510
            .into_pointer()
1✔
511
            .expect("Rc<T> should have a smart pointer definition");
1✔
512

513
        let weak_shape = <RcWeak<String>>::SHAPE;
1✔
514
        let weak_def = weak_shape
1✔
515
            .def
1✔
516
            .into_pointer()
1✔
517
            .expect("RcWeak<T> should have a smart pointer definition");
1✔
518

519
        // 1. Create the strong Rc (rc1)
520
        let rc1_uninit_ptr = rc_shape.allocate().unwrap();
1✔
521
        let new_into_fn = rc_def.vtable.new_into_fn.unwrap();
1✔
522
        let mut value = ManuallyDrop::new(String::from("example"));
1✔
523
        let rc1_ptr =
1✔
524
            unsafe { new_into_fn(rc1_uninit_ptr, PtrMut::new(NonNull::from(&mut value))) };
1✔
525

526
        // 2. Downgrade rc1 to create a weak pointer (weak1)
527
        let weak1_uninit_ptr = weak_shape.allocate().unwrap();
1✔
528
        let downgrade_into_fn = rc_def.vtable.downgrade_into_fn.unwrap();
1✔
529
        // SAFETY: rc1_ptr is valid, weak1_uninit_ptr is allocated for Weak
530
        let weak1_ptr = unsafe { downgrade_into_fn(rc1_ptr, weak1_uninit_ptr) };
1✔
531

532
        // 3. Drop and free the strong pointer (rc1)
533
        let rc_drop_fn = rc_shape.vtable.drop_in_place.unwrap();
1✔
534
        unsafe {
1✔
535
            rc_drop_fn(rc1_ptr);
1✔
536
            rc_shape.deallocate_mut(rc1_ptr).unwrap();
1✔
537
        }
1✔
538

539
        // 4. Attempt to upgrade the weak pointer (weak1)
540
        let upgrade_into_fn = weak_def.vtable.upgrade_into_fn.unwrap();
1✔
541
        let rc2_uninit_ptr = rc_shape.allocate().unwrap();
1✔
542
        // SAFETY: weak1_ptr is valid (though points to dropped data), rc2_uninit_ptr is allocated for Rc
543
        let upgrade_result = unsafe { upgrade_into_fn(weak1_ptr, rc2_uninit_ptr) };
1✔
544

545
        // Assert that the upgrade failed
546
        assert!(
1✔
547
            upgrade_result.is_none(),
1✔
548
            "Upgrade should fail after the strong Rc is dropped"
×
549
        );
550

551
        // 5. Clean up: Deallocate the memory intended for the failed upgrade and drop/deallocate the weak pointer
552
        let weak_drop_fn = weak_shape.vtable.drop_in_place.unwrap();
1✔
553
        unsafe {
1✔
554
            // Deallocate the *uninitialized* memory allocated for the failed upgrade attempt
1✔
555
            rc_shape.deallocate_uninit(rc2_uninit_ptr).unwrap();
1✔
556

1✔
557
            // Drop and deallocate the weak pointer
1✔
558
            weak_drop_fn(weak1_ptr);
1✔
559
            weak_shape.deallocate_mut(weak1_ptr).unwrap();
1✔
560
        }
1✔
561
    }
1✔
562
}
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