Skip to main content

rust_spec/core_impls/
result.rs

1//! Result representation selected by the two variants' size categories.
2
3use core::ops::Add;
4
5use crate::{
6    Gt, Max, Maximum, NonOpaque, RustSpec, Stable, Sum, Unstable, Zero,
7    layout::{LayoutKind, NonRobust, Robust},
8    niche::{NullableRepresentation, WithNiche, WithoutNiche},
9    size::{self, SizedKind},
10};
11
12/// Representation contributions from the alignment of an empty alternative.
13///
14/// Combine these with [NullableRepresentation] using [Add]. Alignment one
15/// preserves the nullable classification; greater alignment prevents relying
16/// on the payload's guaranteed niche representation.
17#[sealed::sealed]
18pub trait NullableAlignment {
19    type Layout: LayoutKind;
20    type Trap;
21    type Niche;
22}
23
24#[sealed::sealed]
25impl NullableAlignment for crate::One {
26    type Layout = Stable;
27    type Trap = Robust;
28    type Niche = WithoutNiche;
29}
30
31#[sealed::sealed]
32impl NullableAlignment for crate::Gt<crate::One> {
33    type Layout = Unstable;
34    type Trap = NonRobust;
35    type Niche = WithNiche<Unstable>;
36}
37
38// Public because its associated types appear in the public RustSpec impl.
39// The containing module keeps this dispatch machinery internal.
40pub trait ResultRepresentation<R: RustSpec, E: RustSpec> {
41    type Layout;
42    type Trap;
43    type Niche;
44    type IndirectTrap;
45}
46
47impl<R, E, K: SizedKind> ResultRepresentation<R, E> for (size::Sized<K>, size::Sized<K>)
48where
49    R: RustSpec<__IndirectTrap: Add<E::__IndirectTrap>>,
50    E: RustSpec,
51{
52    type Layout = Unstable;
53    type Trap = NonRobust;
54    type Niche = WithNiche<Unstable>;
55    type IndirectTrap = Sum<R::__IndirectTrap, E::__IndirectTrap>;
56}
57
58impl<R, E> ResultRepresentation<R, E> for (size::Sized<Gt<Zero>>, size::Sized<Zero>)
59where
60    R: RustSpec<Niche: NullableRepresentation>,
61    E: RustSpec<__Alignment: NullableAlignment>,
62    <E::__Alignment as NullableAlignment>::Layout:
63        Add<<R::Niche as NullableRepresentation>::Layout>,
64    Sum<
65        <E::__Alignment as NullableAlignment>::Layout,
66        <R::Niche as NullableRepresentation>::Layout,
67    >: Add<R::Layout>,
68    <E::__Alignment as NullableAlignment>::Trap: Add<<R::Niche as NullableRepresentation>::Trap>,
69    Sum<<E::__Alignment as NullableAlignment>::Trap, <R::Niche as NullableRepresentation>::Trap>:
70        Add<R::__IndirectTrap>,
71    <E::__Alignment as NullableAlignment>::Niche: Add<<R::Niche as NullableRepresentation>::Niche>,
72{
73    type Layout = Sum<
74        Sum<
75            <E::__Alignment as NullableAlignment>::Layout,
76            <R::Niche as NullableRepresentation>::Layout,
77        >,
78        R::Layout,
79    >;
80    type Trap = Sum<
81        Sum<
82            <E::__Alignment as NullableAlignment>::Trap,
83            <R::Niche as NullableRepresentation>::Trap,
84        >,
85        R::__IndirectTrap,
86    >;
87    type Niche = Sum<
88        <E::__Alignment as NullableAlignment>::Niche,
89        <R::Niche as NullableRepresentation>::Niche,
90    >;
91    type IndirectTrap = R::__IndirectTrap;
92}
93
94impl<R, E> ResultRepresentation<R, E> for (size::Sized<Zero>, size::Sized<Gt<Zero>>)
95where
96    E: RustSpec<Niche: NullableRepresentation>,
97    R: RustSpec<__Alignment: NullableAlignment>,
98    <R::__Alignment as NullableAlignment>::Layout:
99        Add<<E::Niche as NullableRepresentation>::Layout>,
100    Sum<
101        <R::__Alignment as NullableAlignment>::Layout,
102        <E::Niche as NullableRepresentation>::Layout,
103    >: Add<E::Layout>,
104    <R::__Alignment as NullableAlignment>::Trap: Add<<E::Niche as NullableRepresentation>::Trap>,
105    Sum<<R::__Alignment as NullableAlignment>::Trap, <E::Niche as NullableRepresentation>::Trap>:
106        Add<E::__IndirectTrap>,
107    <R::__Alignment as NullableAlignment>::Niche: Add<<E::Niche as NullableRepresentation>::Niche>,
108{
109    type Layout = Sum<
110        Sum<
111            <R::__Alignment as NullableAlignment>::Layout,
112            <E::Niche as NullableRepresentation>::Layout,
113        >,
114        E::Layout,
115    >;
116    type Trap = Sum<
117        Sum<
118            <R::__Alignment as NullableAlignment>::Trap,
119            <E::Niche as NullableRepresentation>::Trap,
120        >,
121        E::__IndirectTrap,
122    >;
123    type Niche = Sum<
124        <R::__Alignment as NullableAlignment>::Niche,
125        <E::Niche as NullableRepresentation>::Niche,
126    >;
127    type IndirectTrap = E::__IndirectTrap;
128}
129
130// SAFETY: The representation helper handles equal-sized categories and either
131// nullable orientation. The remaining axes combine both owned alternatives.
132unsafe impl<R, E> RustSpec for Result<R, E>
133where
134    R: RustSpec<
135            __Alignment: Max<E::__Alignment>,
136            Drop: Add<E::Drop>,
137            Mutability: Add<E::Mutability>,
138        >,
139    E: RustSpec,
140    (R::Size, E::Size): ResultRepresentation<R, E>,
141{
142    type Layout = <(R::Size, E::Size) as ResultRepresentation<R, E>>::Layout;
143    type Size = size::Sized<Gt<Zero>>;
144    type __Alignment = Maximum<R::__Alignment, E::__Alignment>;
145    type Trap = <(R::Size, E::Size) as ResultRepresentation<R, E>>::Trap;
146    type Niche = <(R::Size, E::Size) as ResultRepresentation<R, E>>::Niche;
147    type Drop = Sum<R::Drop, E::Drop>;
148    type Mutability = Sum<R::Mutability, E::Mutability>;
149    type Opacity = NonOpaque;
150    type __IndirectTrap = <(R::Size, E::Size) as ResultRepresentation<R, E>>::IndirectTrap;
151}