twizzler/
marker.rs

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