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#[sealed::sealed]
37impl SizedKind for Zero {}
38
39#[sealed::sealed]
40impl SizedKind for crate::Gt<crate::Zero> {}
41
42#[sealed::sealed]
43impl MetadataKind for SliceLike {}
44
45#[sealed::sealed]
46impl MetadataKind for DynTraitLike {}
47
48/// Pointers to types implementing this trait alias are “thin”.
49///
50/// See [`core::ptr::Thin`]
51pub(crate) trait Thin {}
52impl<K: SizedKind> Thin for Sized<K> {}
53impl Thin for ExternTypeLike {}
54
55pub(crate) trait Dst {}
56impl Dst for ExternTypeLike {}
57impl<K: MetadataKind> Dst for MetaSized<K> {}
58
59impl<K: SizedKind> Add<Sized<K>> for Sized<Zero> {
60    type Output = Sized<K>;
61
62    fn add(self, _: Sized<K>) -> Self::Output {
63        unreachable!()
64    }
65}
66
67impl<K: SizedKind> Add<Sized<K>> for Sized<crate::Gt<crate::Zero>> {
68    type Output = Self;
69
70    fn add(self, _: Sized<K>) -> Self::Output {
71        unreachable!()
72    }
73}
74
75impl<K: Dst, U: SizedKind> Add<K> for Sized<U> {
76    type Output = K;
77
78    fn add(self, _: K) -> Self::Output {
79        unreachable!()
80    }
81}
82
83impl<K: MetadataKind, U: SizedKind> Add<Sized<U>> for MetaSized<K> {
84    type Output = Self;
85
86    fn add(self, _: Sized<U>) -> Self::Output {
87        unreachable!()
88    }
89}
90
91impl<U: SizedKind> Add<Sized<U>> for ExternTypeLike {
92    type Output = Self;
93
94    fn add(self, _: Sized<U>) -> Self::Output {
95        unreachable!()
96    }
97}