Skip to main content

rust_spec/
mutability.rs

1//! Mutability classification of Rust types.
2
3use core::ops::Add;
4
5/// Marker for types whose value requires exclusive access to mutate.
6pub enum Exclusive {}
7
8/// Marker for types with at least one part mutable through shared access.
9///
10/// Any type that carries `Cell<T>` or `UnsafeCell<T>`.
11pub enum WithInterior {}
12
13macro_rules! combine_mutability {
14    ($left:ty, $right:ty => $output:ty) => {
15        impl Add<$right> for $left {
16            type Output = $output;
17
18            fn add(self, _: $right) -> Self::Output {
19                unreachable!()
20            }
21        }
22    };
23}
24
25combine_mutability!(Exclusive, Exclusive => Exclusive);
26combine_mutability!(Exclusive, WithInterior => WithInterior);
27combine_mutability!(WithInterior, Exclusive => WithInterior);
28combine_mutability!(WithInterior, WithInterior => WithInterior);
29
30#[cfg(test)]
31mod tests {
32    #[cfg(feature = "alloc")]
33    use alloc::{boxed::Box, vec::Vec};
34
35    use static_assertions::assert_impl_all;
36
37    use crate::{
38        RustSpec, Stable, Unstable,
39        layout::{NonRobust, Robust},
40        mutability::{Exclusive, WithInterior},
41        niche::{WithNiche, WithoutNiche},
42        size::Sized as Co3Sized,
43    };
44
45    #[test]
46    fn mutability_family_tracks_shared_mutability() {
47        use core::{
48            cell::{Cell, UnsafeCell},
49            ptr::NonNull,
50        };
51
52        assert_impl_all!(u8:
53            RustSpec<
54                Layout = Stable,
55                Size = Co3Sized<crate::Gt<crate::Zero>>,
56                Alignment = crate::One,
57                Trap = Robust,
58                Niche = WithoutNiche,
59                Mutability = Exclusive,
60                __IndirectTrap = Robust,
61            >,
62        );
63        assert_impl_all!(UnsafeCell<u8>:
64            RustSpec<
65                Layout = Stable,
66                Size = Co3Sized<crate::Gt<crate::Zero>>,
67                Alignment = crate::One,
68                Trap = Robust,
69                Niche = WithoutNiche,
70                Mutability = WithInterior,
71                __IndirectTrap = Robust,
72            >,
73        );
74        assert_impl_all!(Cell<u8>:
75            RustSpec<
76                Layout = Stable,
77                Size = Co3Sized<crate::Gt<crate::Zero>>,
78                Alignment = crate::One,
79                Trap = Robust,
80                Niche = WithoutNiche,
81                Mutability = WithInterior,
82                __IndirectTrap = Robust,
83            >,
84        );
85        assert_impl_all!((UnsafeCell<u8>, UnsafeCell<u8>):
86            RustSpec<
87                Layout = Unstable,
88                Size = Co3Sized<crate::Gt<crate::Zero>>,
89                Alignment = crate::One,
90                Trap = Robust,
91                Niche = WithoutNiche,
92                Mutability = WithInterior,
93                __IndirectTrap = Robust,
94            >,
95        );
96        assert_impl_all!((UnsafeCell<u8>, u8):
97            RustSpec<
98                Layout = Unstable,
99                Size = Co3Sized<crate::Gt<crate::Zero>>,
100                Alignment = crate::One,
101                Trap = Robust,
102                Niche = WithoutNiche,
103                Mutability = WithInterior,
104                __IndirectTrap = Robust,
105            >,
106        );
107        assert_impl_all!([UnsafeCell<u8>; 2]:
108            RustSpec<
109                Layout = Stable,
110                Size = Co3Sized<crate::Gt<crate::Zero>>,
111                Alignment = crate::One,
112                Trap = Robust,
113                Niche = WithoutNiche,
114                Mutability = WithInterior,
115                __IndirectTrap = Robust,
116            >,
117        );
118        assert_impl_all!([u8; 2]:
119            RustSpec<
120                Layout = Stable,
121                Size = Co3Sized<crate::Gt<crate::Zero>>,
122                Alignment = crate::One,
123                Trap = Robust,
124                Niche = WithoutNiche,
125                Mutability = Exclusive,
126                __IndirectTrap = Robust,
127            >,
128        );
129        assert_impl_all!(&UnsafeCell<u8>:
130            RustSpec<
131                Layout = Stable,
132                Size = Co3Sized<crate::Gt<crate::Zero>>,
133                Alignment = <usize as RustSpec>::Alignment,
134                Trap = NonRobust,
135                Niche = WithNiche<Stable>,
136                Mutability = Exclusive,
137                __IndirectTrap = Robust,
138            >,
139        );
140        assert_impl_all!(&mut UnsafeCell<u8>:
141            RustSpec<
142                Layout = Stable,
143                Size = Co3Sized<crate::Gt<crate::Zero>>,
144                Alignment = <usize as RustSpec>::Alignment,
145                Trap = NonRobust,
146                Niche = WithNiche<Stable>,
147                Mutability = Exclusive,
148                __IndirectTrap = Robust,
149            >,
150        );
151        assert_impl_all!(*const UnsafeCell<u8>:
152            RustSpec<
153                Layout = Stable,
154                Size = Co3Sized<crate::Gt<crate::Zero>>,
155                Alignment = <usize as RustSpec>::Alignment,
156                Trap = Robust,
157                Niche = WithoutNiche,
158                Mutability = Exclusive,
159                __IndirectTrap = Robust,
160            >,
161        );
162        assert_impl_all!(*mut UnsafeCell<u8>:
163            RustSpec<
164                Layout = Stable,
165                Size = Co3Sized<crate::Gt<crate::Zero>>,
166                Alignment = <usize as RustSpec>::Alignment,
167                Trap = Robust,
168                Niche = WithoutNiche,
169                Mutability = Exclusive,
170                __IndirectTrap = Robust,
171            >,
172        );
173        assert_impl_all!(NonNull<UnsafeCell<u8>>:
174            RustSpec<
175                Layout = Stable,
176                Size = Co3Sized<crate::Gt<crate::Zero>>,
177                Alignment = <usize as RustSpec>::Alignment,
178                Trap = NonRobust,
179                Niche = WithNiche<Stable>,
180                Mutability = Exclusive,
181                __IndirectTrap = Robust,
182            >,
183        );
184        assert_impl_all!(Option<UnsafeCell<u8>>:
185            RustSpec<
186                Layout = Unstable,
187                Size = Co3Sized<crate::Gt<crate::Zero>>,
188                Alignment = crate::One,
189                Trap = NonRobust,
190                Niche = WithNiche<Unstable>,
191                Mutability = Exclusive,
192                __IndirectTrap = Robust,
193            >,
194        );
195
196        #[cfg(feature = "alloc")]
197        assert_impl_all!(Box<UnsafeCell<u8>>:
198            RustSpec<
199                Layout = Stable,
200                Size = Co3Sized<crate::Gt<crate::Zero>>,
201                Alignment = <usize as RustSpec>::Alignment,
202                Trap = NonRobust,
203                Niche = WithNiche<Stable>,
204                Mutability = Exclusive,
205                __IndirectTrap = Robust,
206            >,
207        );
208        #[cfg(feature = "alloc")]
209        assert_impl_all!(Box<[UnsafeCell<u8>]>:
210            RustSpec<
211                Layout = Unstable,
212                Size = Co3Sized<crate::Gt<crate::Zero>>,
213                Alignment = <usize as RustSpec>::Alignment,
214                Trap = NonRobust,
215                Niche = WithNiche<Unstable>,
216                Mutability = Exclusive,
217                __IndirectTrap = Robust,
218            >,
219        );
220        #[cfg(feature = "alloc")]
221        assert_impl_all!(Vec<UnsafeCell<u8>>:
222            RustSpec<
223                Layout = Unstable,
224                Size = Co3Sized<crate::Gt<crate::Zero>>,
225                Alignment = <usize as RustSpec>::Alignment,
226                Trap = NonRobust,
227                Niche = WithNiche<Unstable>,
228                Mutability = Exclusive,
229                __IndirectTrap = Robust,
230            >,
231        );
232    }
233}