facet_core/impls_core/
smartptr.rs

1use crate::{
2    Def, Facet, Field, FieldFlags, KnownSmartPointer, PtrConst, Repr, SmartPointerDef,
3    SmartPointerFlags, SmartPointerVTable, StructKind, StructType, Type, UserType, ValueVTable,
4    value_vtable,
5};
6
7unsafe impl<'a, T: Facet<'a>> Facet<'a> for core::ptr::NonNull<T> {
8    const VTABLE: &'static ValueVTable =
9        &const { value_vtable!(core::ptr::NonNull<T>, |f, _opts| write!(f, "NonNull")) };
10
11    const SHAPE: &'static crate::Shape<'static> = &const {
12        crate::Shape::builder_for_sized::<Self>()
13            .type_params(&[crate::TypeParam {
14                name: "T",
15                shape: || T::SHAPE,
16            }])
17            .ty(Type::User(UserType::Struct(StructType {
18                repr: Repr::transparent(),
19                kind: StructKind::Struct,
20                fields: &const {
21                    [Field::builder()
22                        .name("pointer")
23                        .shape(<*mut T>::SHAPE)
24                        .offset(0)
25                        .flags(FieldFlags::EMPTY)
26                        .build()]
27                },
28            })))
29            .def(Def::SmartPointer(
30                SmartPointerDef::builder()
31                    .pointee(|| T::SHAPE)
32                    .flags(SmartPointerFlags::EMPTY)
33                    .known(KnownSmartPointer::NonNull)
34                    .vtable(
35                        &const {
36                            SmartPointerVTable::builder()
37                                .borrow_fn(|this| {
38                                    let ptr = unsafe { this.get::<Self>().as_ptr() };
39                                    PtrConst::new(ptr)
40                                })
41                                .new_into_fn(|this, ptr| {
42                                    let ptr = unsafe { ptr.read::<*mut T>() };
43                                    let non_null =
44                                        unsafe { core::ptr::NonNull::new_unchecked(ptr) };
45                                    unsafe { this.put(non_null) }
46                                })
47                                .build()
48                        },
49                    )
50                    .build(),
51            ))
52            .build()
53    };
54}