use core::{convert::Infallible, ops::Add};
use crate::{
Stable, Unstable,
layout::{LayoutKind, NonRobust, Robust},
};
pub enum WithoutNiche {}
pub struct WithNiche<K>(core::marker::PhantomData<K>, Infallible);
#[sealed::sealed]
pub trait NullableRepresentation {
type Layout: LayoutKind;
type Trap;
type Niche;
}
#[sealed::sealed]
impl NullableRepresentation for WithoutNiche {
type Layout = Unstable;
type Trap = NonRobust;
type Niche = WithNiche<Unstable>;
}
#[sealed::sealed]
impl NullableRepresentation for WithNiche<Unstable> {
type Layout = Unstable;
type Trap = NonRobust;
type Niche = WithNiche<Unstable>;
}
#[sealed::sealed]
impl NullableRepresentation for WithNiche<Stable> {
type Layout = Stable;
type Trap = Robust;
type Niche = WithoutNiche;
}
impl Add for WithoutNiche {
type Output = Self;
fn add(self, _: Self) -> Self::Output {
unreachable!()
}
}
impl<K: LayoutKind> Add<WithNiche<K>> for WithoutNiche {
type Output = WithNiche<Unstable>;
fn add(self, _: WithNiche<K>) -> Self::Output {
unreachable!()
}
}
impl<K: LayoutKind> Add<WithoutNiche> for WithNiche<K> {
type Output = WithNiche<Unstable>;
fn add(self, _: WithoutNiche) -> Self::Output {
unreachable!()
}
}
impl<K: LayoutKind, U: LayoutKind> Add<WithNiche<U>> for WithNiche<K> {
type Output = WithNiche<Unstable>;
fn add(self, _: WithNiche<U>) -> Self::Output {
unreachable!()
}
}
#[cfg(test)]
mod tests {
use core::num::NonZero as StdNonZero;
use static_assertions::assert_impl_all;
use super::*;
use crate::{
RustSpec,
mutability::{Exclusive, WithoutInterior},
};
#[test]
fn nested_option_niche_family() {
assert_impl_all!(Option<bool>:
RustSpec<
Layout = Unstable,
Size = crate::size::Sized<crate::Gt<crate::Zero>>,
__Alignment = crate::One,
Trap = NonRobust,
Niche = WithNiche<crate::Unstable>,
Mutability = Exclusive<WithoutInterior>,
__IndirectTrap = Robust,
>,
);
assert_impl_all!(Option<Option<bool>>:
RustSpec<
Layout = Unstable,
Size = crate::size::Sized<crate::Gt<crate::Zero>>,
__Alignment = crate::One,
Trap = NonRobust,
Niche = WithNiche<crate::Unstable>,
Mutability = Exclusive<WithoutInterior>,
__IndirectTrap = Robust,
>,
);
assert_impl_all!(Option<(u8, StdNonZero<u8>)>:
RustSpec<
Layout = Unstable,
Size = crate::size::Sized<crate::Gt<crate::Zero>>,
__Alignment = crate::One,
Trap = NonRobust,
Niche = WithNiche<crate::Unstable>,
Mutability = Exclusive<WithoutInterior>,
__IndirectTrap = Robust,
>,
);
}
}