1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use core::marker::PhantomData;
use core::ptr::NonNull;
use core::raw::TraitObject;

/// The vtable of a type with a `Reified` field as its first struct member,
/// from which a trait object can be constructed from a thin pointer to the
/// base address of the object.
///
/// # Safety
///
/// Can only reify a type that has a `Reified` field as its first struct member.
#[repr(C)]
pub struct Reified<T: ?Sized> {
    /// Pointer to the vtable of the concrete type of the object whose base
    /// address equals the address of this `Reified` structure.
    vtable: NonNull<()>,
    marker: PhantomData<*const T>,
}

impl<T: ?Sized> Reified<T> {
    /// Returns a new `Reified` structure with an uninitialized vtable.
    #[inline]
    pub const unsafe fn uninitialized() -> Reified<T> {
        Reified {
            vtable: NonNull::new_unchecked(1 as *mut ()),
            marker: PhantomData,
        }
    }

    /// Initializes the vtable of the `Reified` structure, which resides at the
    /// base address of the referenced `object`, to point to the vtable of the
    /// passed-in trait object.
    ///
    /// # Safety
    ///
    /// Assumes that the concrete `object` type has a `Reified` field as its
    /// first struct member.
    #[inline]
    pub unsafe fn deify(object: TraitObject) {
        let base = object.data as *mut Reified<T>;
        (*base).vtable = NonNull::new_unchecked(object.vtable);
    }

    /// Returns a trait object for the concrete type of the object whose base
    /// address equals the address of the passed-in `Reified` reference.
    ///
    /// # Safety
    ///
    /// Assumes that the address of the passed-in `Reified` reference equals
    /// the address of an object, and that the concrete object type's vtable
    /// pointer equals the vtable pointer contained in the `Reified` structure.
    #[inline]
    pub unsafe fn reify(&self) -> TraitObject {
        TraitObject {
            data: self as *const Reified<T> as *mut (),
            vtable: self.vtable.as_ptr(),
        }
    }
}

/// A type with a `Reified` field as its first struct member, from which a
/// polymorphic trait object can be constructed from a thin pointer to the
/// base address of the object.
///
/// # Safety
///
/// Can only reify a type that has a `Reified` field as its first struct member.
pub trait Reify<'a, T: ?Sized = Self> {
    /// Initialized the `Reified` structure at the base address of the `object`
    /// reference to the vtable of the `object` instance.
    unsafe fn deify(object: &mut T);

    /// Returns a polymorphic trait object for the concrete type of the object
    /// whose base address equals the address of the passed-in `Reified`
    /// reference.
    unsafe fn reify(base: &'a Reified<T>) -> &'a T;
}