Skip to main content

extern_trait/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3
4pub use extern_trait_impl::*;
5
6/// Opaque representation used to store implementation types in proxy structs.
7///
8/// This type is two pointers in size, which means implementation types must be
9/// at most `2 * size_of::<usize>()` bytes (16 bytes on 64-bit, 8 bytes on 32-bit).
10///
11/// The size constraint is checked at compile time.
12#[doc(hidden)]
13#[derive(Clone, Copy)]
14#[repr(C)]
15pub struct Repr(
16    *mut (),
17    *mut (),
18    // make this type `!Send + !Sync + !Unpin + !UnwindSafe + !RefUnwindSafe + !Freeze`
19    core::marker::PhantomData<(
20        &'static mut (),
21        core::cell::UnsafeCell<()>,
22        core::marker::PhantomPinned,
23    )>,
24);
25
26const _: () = assert!(size_of::<Repr>() == size_of::<usize>() * 2);
27
28impl Repr {
29    #[doc(hidden)]
30    #[inline]
31    pub unsafe fn from_value<T: Sized>(value: T) -> Self {
32        const { assert!(size_of::<T>() <= size_of::<Repr>()) };
33        let mut repr = core::mem::MaybeUninit::<Repr>::zeroed();
34        // SAFETY: We just asserted that size_of::<T>() <= size_of::<Repr>()
35        unsafe {
36            core::ptr::write(repr.as_mut_ptr().cast::<T>(), value);
37            repr.assume_init()
38        }
39    }
40
41    #[doc(hidden)]
42    #[inline]
43    pub unsafe fn into_value<T: Sized>(self) -> T {
44        const { assert!(size_of::<T>() <= size_of::<Repr>()) };
45        // SAFETY: We require that size_of::<T>() <= size_of::<Repr>(),
46        // and the caller ensures the Repr was created from a valid T.
47        unsafe { core::ptr::read((&self as *const Repr).cast::<T>()) }
48    }
49}
50
51#[doc(hidden)]
52pub mod __private {
53    #[doc(hidden)]
54    pub use typeid::ConstTypeId;
55}