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,) {}
36unsafe impl<A: Invariant, B: Invariant> Invariant for (A, B) {}
37
38unsafe impl<T: Invariant> Invariant for Option<T> {}
39unsafe impl<R: Invariant, E: Invariant> Invariant for Result<R, E> {}
40
41/// The type may move between objects without side effects. Notably, this is
42/// not implemented for invariant pointers or types that contain them, since an invariant pointer
43/// may reference an object's Foreign Object Table. This is a little restrictive (technically
44/// intra-object pointers are safe to move intra-object), but it's the best we can do at
45/// compile-time.
46///
47/// # Safety
48/// The implementation must ensure that no store side effects must occur when writing this value to
49/// object memory.
50pub unsafe auto trait StoreCopy {}
51
52/// A zero-sized phantom marker for indicating that the containing type has a side effect when
53/// storing (e.g. it has an invariant pointer).
54#[derive(Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, Debug)]
55pub struct PhantomStoreEffect;
56
57impl !StoreCopy for PhantomStoreEffect {}
58impl !Unpin for PhantomStoreEffect {}
59#[rustc_on_unimplemented(
60    message = "`{Self}` is not safe to be stored as an object's base",
61    label = "`{Self}` is not safe to be stored as an object's base"
62)]
63pub trait BaseType {
64    /// The fingerprint of this type.
65    fn fingerprint() -> u64 {
66        0
67    }
68}
69
70impl BaseType for () {}
71impl BaseType for u8 {}
72impl BaseType for u16 {}
73impl BaseType for u32 {}
74impl BaseType for u64 {}
75
76impl BaseType for ThreadRepr {}