1use super::*;
2
3/// A trait which indicates that a type is a `#[repr(transparent)]` wrapper
4/// around the `Inner` value.
5///
6/// This allows safely copy transmuting between the `Inner` type and the
7/// `TransparentWrapper` type. Functions like `wrap_{}` convert from the inner
8/// type to the wrapper type and `peel_{}` functions do the inverse conversion
9/// from the wrapper type to the inner type. We deliberately do not call the
10/// wrapper-removing methods "unwrap" because at this point that word is too
11/// strongly tied to the Option/ Result methods.
12///
13/// # Safety
14///
15/// The safety contract of `TransparentWrapper` is relatively simple:
16///
17/// For a given `Wrapper` which implements `TransparentWrapper<Inner>`:
18///
19/// 1. `Wrapper` must be a wrapper around `Inner` with an identical data
20/// representations. This either means that it must be a
21/// `#[repr(transparent)]` struct which contains a either a field of type
22/// `Inner` (or a field of some other transparent wrapper for `Inner`) as
23/// the only non-ZST field.
24///
25/// 2. Any fields *other* than the `Inner` field must be trivially constructable
26/// ZSTs, for example `PhantomData`, `PhantomPinned`, etc. (When deriving
27/// `TransparentWrapper` on a type with ZST fields, the ZST fields must be
28/// [`Zeroable`]).
29///
30/// 3. The `Wrapper` may not impose additional alignment requirements over
31/// `Inner`.
32/// - Note: this is currently guaranteed by `repr(transparent)`, but there
33/// have been discussions of lifting it, so it's stated here explicitly.
34///
35/// 4. All functions on `TransparentWrapper` **may not** be overridden.
36///
37/// ## Caveats
38///
39/// If the wrapper imposes additional constraints upon the inner type which are
40/// required for safety, it's responsible for ensuring those still hold -- this
41/// generally requires preventing access to instances of the inner type, as
42/// implementing `TransparentWrapper<U> for T` means anybody can call
43/// `T::cast_ref(any_instance_of_u)`.
44///
45/// For example, it would be invalid to implement TransparentWrapper for `str`
46/// to implement `TransparentWrapper` around `[u8]` because of this.
47///
48/// # Examples
49///
50/// ## Basic
51///
52/// ```
53/// use bytemuck::TransparentWrapper;
54/// # #[derive(Default)]
55/// # struct SomeStruct(u32);
56///
57/// #[repr(transparent)]
58/// struct MyWrapper(SomeStruct);
59///
60/// unsafe impl TransparentWrapper<SomeStruct> for MyWrapper {}
61///
62/// // interpret a reference to &SomeStruct as a &MyWrapper
63/// let thing = SomeStruct::default();
64/// let inner_ref: &MyWrapper = MyWrapper::wrap_ref(&thing);
65///
66/// // Works with &mut too.
67/// let mut mut_thing = SomeStruct::default();
68/// let inner_mut: &mut MyWrapper = MyWrapper::wrap_mut(&mut mut_thing);
69///
70/// # let _ = (inner_ref, inner_mut); // silence warnings
71/// ```
72///
73/// ## Use with dynamically sized types
74///
75/// ```
76/// use bytemuck::TransparentWrapper;
77///
78/// #[repr(transparent)]
79/// struct Slice<T>([T]);
80///
81/// unsafe impl<T> TransparentWrapper<[T]> for Slice<T> {}
82///
83/// let s = Slice::wrap_ref(&[1u32, 2, 3]);
84/// assert_eq!(&s.0, &[1, 2, 3]);
85///
86/// let mut buf = [1, 2, 3u8];
87/// let sm = Slice::wrap_mut(&mut buf);
88/// ```
89///
90/// ## Deriving
91///
92/// When deriving, the non-wrapped fields must uphold all the normal requirements,
93/// and must also be `Zeroable`.
94///
95#[cfg_attr(feature = "derive", doc = "```")]
96#[cfg_attr(
97 not(feature = "derive"),
98 doc = "```ignore
99// This example requires the `derive` feature."
100)]
101/// use bytemuck::TransparentWrapper;
102/// use std::marker::PhantomData;
103///
104/// #[derive(TransparentWrapper)]
105/// #[repr(transparent)]
106/// #[transparent(usize)]
107/// struct Wrapper<T: ?Sized>(usize, PhantomData<T>); // PhantomData<T> implements Zeroable for all T
108/// ```
109///
110/// Here, an error will occur, because `MyZst` does not implement `Zeroable`.
111///
112#[cfg_attr(feature = "derive", doc = "```compile_fail")]
113#[cfg_attr(
114 not(feature = "derive"),
115 doc = "```ignore
116// This example requires the `derive` feature."
117)]
118/// use bytemuck::TransparentWrapper;
119/// struct MyZst;
120///
121/// #[derive(TransparentWrapper)]
122/// #[repr(transparent)]
123/// #[transparent(usize)]
124/// struct Wrapper(usize, MyZst); // MyZst does not implement Zeroable
125/// ```
126pub unsafe trait TransparentWrapper<Inner: ?Sized> {
127 /// Convert the inner type into the wrapper type.
128 #[inline]
129 fn wrap(s: Inner) -> Self
130 where
131 Self: Sized,
132 Inner: Sized,
133 {
134 // SAFETY: The unsafe contract requires that `Self` and `Inner` have
135 // identical representations.
136 unsafe { transmute!(s) }
137 }
138
139 /// Convert a reference to the inner type into a reference to the wrapper
140 /// type.
141 #[inline]
142 fn wrap_ref(s: &Inner) -> &Self {
143 unsafe {
144 assert!(size_of::<*const Inner>() == size_of::<*const Self>());
145 // A pointer cast doesn't work here because rustc can't tell that
146 // the vtables match (because of the `?Sized` restriction relaxation).
147 // A `transmute` doesn't work because the sizes are unspecified.
148 //
149 // SAFETY: The unsafe contract requires that these two have
150 // identical representations.
151 let inner_ptr = s as *const Inner;
152 let wrapper_ptr: *const Self = transmute!(inner_ptr);
153 &*wrapper_ptr
154 }
155 }
156
157 /// Convert a mutable reference to the inner type into a mutable reference to
158 /// the wrapper type.
159 #[inline]
160 fn wrap_mut(s: &mut Inner) -> &mut Self {
161 unsafe {
162 assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
163 // A pointer cast doesn't work here because rustc can't tell that
164 // the vtables match (because of the `?Sized` restriction relaxation).
165 // A `transmute` doesn't work because the sizes are unspecified.
166 //
167 // SAFETY: The unsafe contract requires that these two have
168 // identical representations.
169 let inner_ptr = s as *mut Inner;
170 let wrapper_ptr: *mut Self = transmute!(inner_ptr);
171 &mut *wrapper_ptr
172 }
173 }
174
175 /// Convert a slice to the inner type into a slice to the wrapper type.
176 #[inline]
177 fn wrap_slice(s: &[Inner]) -> &[Self]
178 where
179 Self: Sized,
180 Inner: Sized,
181 {
182 unsafe {
183 assert!(size_of::<*const Inner>() == size_of::<*const Self>());
184 assert!(align_of::<*const Inner>() == align_of::<*const Self>());
185 // SAFETY: The unsafe contract requires that these two have
186 // identical representations (size and alignment).
187 core::slice::from_raw_parts(s.as_ptr() as *const Self, s.len())
188 }
189 }
190
191 /// Convert a mutable slice to the inner type into a mutable slice to the
192 /// wrapper type.
193 #[inline]
194 fn wrap_slice_mut(s: &mut [Inner]) -> &mut [Self]
195 where
196 Self: Sized,
197 Inner: Sized,
198 {
199 unsafe {
200 assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
201 assert!(align_of::<*mut Inner>() == align_of::<*mut Self>());
202 // SAFETY: The unsafe contract requires that these two have
203 // identical representations (size and alignment).
204 core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Self, s.len())
205 }
206 }
207
208 /// Convert the wrapper type into the inner type.
209 #[inline]
210 fn peel(s: Self) -> Inner
211 where
212 Self: Sized,
213 Inner: Sized,
214 {
215 unsafe { transmute!(s) }
216 }
217
218 /// Convert a reference to the wrapper type into a reference to the inner
219 /// type.
220 #[inline]
221 fn peel_ref(s: &Self) -> &Inner {
222 unsafe {
223 assert!(size_of::<*const Inner>() == size_of::<*const Self>());
224 // A pointer cast doesn't work here because rustc can't tell that
225 // the vtables match (because of the `?Sized` restriction relaxation).
226 // A `transmute` doesn't work because the sizes are unspecified.
227 //
228 // SAFETY: The unsafe contract requires that these two have
229 // identical representations.
230 let wrapper_ptr = s as *const Self;
231 let inner_ptr: *const Inner = transmute!(wrapper_ptr);
232 &*inner_ptr
233 }
234 }
235
236 /// Convert a mutable reference to the wrapper type into a mutable reference
237 /// to the inner type.
238 #[inline]
239 fn peel_mut(s: &mut Self) -> &mut Inner {
240 unsafe {
241 assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
242 // A pointer cast doesn't work here because rustc can't tell that
243 // the vtables match (because of the `?Sized` restriction relaxation).
244 // A `transmute` doesn't work because the sizes are unspecified.
245 //
246 // SAFETY: The unsafe contract requires that these two have
247 // identical representations.
248 let wrapper_ptr = s as *mut Self;
249 let inner_ptr: *mut Inner = transmute!(wrapper_ptr);
250 &mut *inner_ptr
251 }
252 }
253
254 /// Convert a slice to the wrapped type into a slice to the inner type.
255 #[inline]
256 fn peel_slice(s: &[Self]) -> &[Inner]
257 where
258 Self: Sized,
259 Inner: Sized,
260 {
261 unsafe {
262 assert!(size_of::<*const Inner>() == size_of::<*const Self>());
263 assert!(align_of::<*const Inner>() == align_of::<*const Self>());
264 // SAFETY: The unsafe contract requires that these two have
265 // identical representations (size and alignment).
266 core::slice::from_raw_parts(s.as_ptr() as *const Inner, s.len())
267 }
268 }
269
270 /// Convert a mutable slice to the wrapped type into a mutable slice to the
271 /// inner type.
272 #[inline]
273 fn peel_slice_mut(s: &mut [Self]) -> &mut [Inner]
274 where
275 Self: Sized,
276 Inner: Sized,
277 {
278 unsafe {
279 assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
280 assert!(align_of::<*mut Inner>() == align_of::<*mut Self>());
281 // SAFETY: The unsafe contract requires that these two have
282 // identical representations (size and alignment).
283 core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Inner, s.len())
284 }
285 }
286}
287
288unsafe impl<T> TransparentWrapper<T> for core::num::Wrapping<T> {}
289