Skip to main content

rust_spec/
size.rs

1use core::{convert::Infallible, ops::Add};
2
3pub use crate::{Gt, Zero};
4
5#[sealed::sealed]
6pub trait SizedKind {}
7
8#[sealed::sealed]
9pub trait MetadataKind {}
10
11/// Marker for types with a constant size known at compile time.
12///
13/// See [`core::marker::Sized`].
14pub struct Sized<K: SizedKind>(core::marker::PhantomData<K>, Infallible);
15
16/// Marker for types with a size that can be determined from pointer metadata.
17///
18/// Type parameter can be set to either [`SliceLike`] or [`DynTraitLike`] only.
19///
20/// See [`core::marker::MetaSized`]
21pub struct MetaSized<K: MetadataKind>(core::marker::PhantomData<K>, Infallible);
22
23/// Marker for [Slices](https://doc.rust-lang.org/core/primitive.slice.html) or DSTs whose last field is a slice.
24///
25/// See [`core::slice`].
26pub enum SliceLike {}
27
28/// Marker for [Trait objects](https://doc.rust-lang.org/reference/types/trait-object.html) or DSTs whose last field is a trait object.
29pub enum DynTraitLike {}
30
31/// Marker for [Extern types](https://rust-lang.github.io/rfcs/1861-extern-types.html) and DSTs whose last field is an extern type.
32///
33/// Pointers to extern types are thin.
34pub enum ExternTypeLike {}
35
36/// Unsized data whose length can be found from a nul terminator.
37pub enum NulTerminated {}
38
39#[sealed::sealed]
40impl SizedKind for Zero {}
41
42#[sealed::sealed]
43impl SizedKind for crate::Gt<crate::Zero> {}
44
45#[sealed::sealed]
46impl MetadataKind for SliceLike {}
47
48#[sealed::sealed]
49impl MetadataKind for DynTraitLike {}
50
51/// Pointers to types implementing this trait alias are “thin”.
52///
53/// See [`core::ptr::Thin`]
54pub(crate) trait Thin {}
55impl<K: SizedKind> Thin for Sized<K> {}
56impl Thin for ExternTypeLike {}
57
58pub(crate) trait Dst {}
59impl Dst for ExternTypeLike {}
60impl Dst for NulTerminated {}
61impl<K: MetadataKind> Dst for MetaSized<K> {}
62
63impl<K: SizedKind> Add<Sized<K>> for Sized<Zero> {
64    type Output = Sized<K>;
65
66    fn add(self, _: Sized<K>) -> Self::Output {
67        unreachable!()
68    }
69}
70
71impl<K: SizedKind> Add<Sized<K>> for Sized<crate::Gt<crate::Zero>> {
72    type Output = Self;
73
74    fn add(self, _: Sized<K>) -> Self::Output {
75        unreachable!()
76    }
77}
78
79impl<K: Dst, U: SizedKind> Add<K> for Sized<U> {
80    type Output = K;
81
82    fn add(self, _: K) -> Self::Output {
83        unreachable!()
84    }
85}
86
87impl<K: MetadataKind, U: SizedKind> Add<Sized<U>> for MetaSized<K> {
88    type Output = Self;
89
90    fn add(self, _: Sized<U>) -> Self::Output {
91        unreachable!()
92    }
93}
94
95impl<U: SizedKind> Add<Sized<U>> for ExternTypeLike {
96    type Output = Self;
97
98    fn add(self, _: Sized<U>) -> Self::Output {
99        unreachable!()
100    }
101}
102
103impl<U: SizedKind> Add<Sized<U>> for NulTerminated {
104    type Output = Self;
105
106    fn add(self, _: Sized<U>) -> Self::Output {
107        unreachable!()
108    }
109}