twizzler_rt_abi/
marker.rs

1/// Indicates that a type is _invariant_ and thus can be stored in an object.
2///
3/// # Safety
4/// The implementation must ensure that the type is invariant, meaning that the type must:
5///   - Be FFI safe.
6///   - Be stable in-memory (independent of architecture). This means, among other things, that the
7///     type must be fixed-width. For example, usize is not `Invariant`.
8#[rustc_on_unimplemented(
9    message = "`{Self}` is not safe to be stored in an object",
10    label = "`{Self}` is not safe to be stored in an object"
11)]
12pub unsafe trait Invariant {}
13
14unsafe impl Invariant for u8 {}
15unsafe impl Invariant for u16 {}
16unsafe impl Invariant for u32 {}
17unsafe impl Invariant for u64 {}
18unsafe impl Invariant for bool {}
19unsafe impl Invariant for i8 {}
20unsafe impl Invariant for i16 {}
21unsafe impl Invariant for i32 {}
22unsafe impl Invariant for i64 {}
23
24unsafe impl Invariant for f64 {}
25unsafe impl Invariant for f32 {}
26
27unsafe impl Invariant for () {}
28
29unsafe impl<T: Invariant, const N: usize> Invariant for [T; N] {}
30
31unsafe impl<T: Invariant> Invariant for (T,) {}
32unsafe impl<A: Invariant, B: Invariant> Invariant for (A, B) {}
33
34unsafe impl<T: Invariant> Invariant for Option<T> {}
35unsafe impl<R: Invariant, E: Invariant> Invariant for Result<R, E> {}
36
37/// The type may move between objects without side effects. Notably, this is
38/// not implemented for invariant pointers or types that contain them, since an invariant pointer
39/// may reference an object's Foreign Object Table. This is a little restrictive (technically
40/// intra-object pointers are safe to move intra-object), but it's the best we can do at
41/// compile-time.
42///
43/// # Safety
44/// The implementation must ensure that no store side effects must occur when writing this value to
45/// object memory.
46pub unsafe auto trait StoreCopy {}
47
48/// A zero-sized phantom marker for indicating that the containing type has a side effect when
49/// storing (e.g. it has an invariant pointer).
50#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, Debug)]
51pub struct PhantomStoreEffect;
52
53impl !StoreCopy for PhantomStoreEffect {}
54impl !Unpin for PhantomStoreEffect {}
55#[rustc_on_unimplemented(
56    message = "`{Self}` is not safe to be stored as an object's base",
57    label = "`{Self}` is not safe to be stored as an object's base"
58)]
59pub trait BaseType {
60    /// The fingerprint of this type.
61    fn fingerprint() -> u64 {
62        0
63    }
64}
65
66impl BaseType for () {}
67impl BaseType for u8 {}
68impl BaseType for u16 {}
69impl BaseType for u32 {}
70impl BaseType for u64 {}