Skip to main content

rust_spec/
mutability.rs

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