Skip to main content

rust_spec/
niche.rs

1//! Logic related to the conversion of [`Option<T>`] to and from FFI-compatible representation
2
3use core::{convert::Infallible, ops::Add};
4
5use crate::{Stable, Unstable};
6
7#[sealed::sealed]
8pub trait NicheStabilityKind {}
9
10/// Marker for a type that has no trap representations and therefore no niche value
11pub enum WithoutNiche {}
12
13/// Marker for a type that has a niche value.
14pub struct WithNiche<K: NicheStabilityKind>(core::marker::PhantomData<K>, Infallible);
15
16#[sealed::sealed]
17impl NicheStabilityKind for Stable {}
18
19#[sealed::sealed]
20impl NicheStabilityKind for Unstable {}
21
22impl Add for WithoutNiche {
23    type Output = Self;
24
25    fn add(self, _: Self) -> Self::Output {
26        unreachable!()
27    }
28}
29impl<K: NicheStabilityKind> Add<WithNiche<K>> for WithoutNiche {
30    type Output = WithNiche<Unstable>;
31
32    fn add(self, _: WithNiche<K>) -> Self::Output {
33        unreachable!()
34    }
35}
36impl<K: NicheStabilityKind> Add<WithoutNiche> for WithNiche<K> {
37    type Output = WithNiche<Unstable>;
38
39    fn add(self, _: WithoutNiche) -> Self::Output {
40        unreachable!()
41    }
42}
43impl<K: NicheStabilityKind, U: NicheStabilityKind> Add<WithNiche<U>> for WithNiche<K> {
44    type Output = WithNiche<Unstable>;
45
46    fn add(self, _: WithNiche<U>) -> Self::Output {
47        unreachable!()
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use core::num::NonZero as StdNonZero;
54
55    use static_assertions::assert_impl_all;
56
57    use super::*;
58    use crate::{
59        RustSpec, Unstable,
60        layout::{NonRobust, Robust},
61        mutability::Exclusive,
62    };
63
64    #[test]
65    fn nested_option_niche_family() {
66        assert_impl_all!(Option<bool>:
67            RustSpec<
68                Layout = Unstable,
69                Size = crate::size::Sized<crate::Gt<crate::Zero>>,
70                Alignment = crate::One,
71                Trap = NonRobust,
72                Niche = WithNiche<crate::Unstable>,
73                Mutability = Exclusive,
74                __IndirectTrap = Robust,
75            >,
76        );
77
78        assert_impl_all!(Option<Option<bool>>:
79            RustSpec<
80                Layout = Unstable,
81                Size = crate::size::Sized<crate::Gt<crate::Zero>>,
82                Alignment = crate::One,
83                Trap = NonRobust,
84                Niche = WithNiche<crate::Unstable>,
85                Mutability = Exclusive,
86                __IndirectTrap = Robust,
87            >,
88        );
89
90        assert_impl_all!(Option<(u8, StdNonZero<u8>)>:
91            RustSpec<
92                Layout = Unstable,
93                Size = crate::size::Sized<crate::Gt<crate::Zero>>,
94                Alignment = crate::One,
95                Trap = NonRobust,
96                // FIXME: The type should be WithoutNiche
97                Niche = WithNiche<crate::Unstable>,
98                Mutability = Exclusive,
99                __IndirectTrap = Robust,
100            >,
101        );
102    }
103}