1 use 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 /// ```
126 pub unsafe trait TransparentWrapper<Inner: ?Sized> {
127   /// Convert the inner type into the wrapper type.
128   #[inline]
wrap(s: Inner) -> Self where Self: Sized, Inner: Sized,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]
wrap_ref(s: &Inner) -> &Self142   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]
wrap_mut(s: &mut Inner) -> &mut Self160   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]
wrap_slice(s: &[Inner]) -> &[Self] where Self: Sized, Inner: Sized,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]
wrap_slice_mut(s: &mut [Inner]) -> &mut [Self] where Self: Sized, Inner: Sized,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]
peel(s: Self) -> Inner where Self: Sized, Inner: Sized,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]
peel_ref(s: &Self) -> &Inner221   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]
peel_mut(s: &mut Self) -> &mut Inner239   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]
peel_slice(s: &[Self]) -> &[Inner] where Self: Sized, Inner: Sized,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]
peel_slice_mut(s: &mut [Self]) -> &mut [Inner] where Self: Sized, Inner: Sized,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 
288 unsafe impl<T> TransparentWrapper<T> for core::num::Wrapping<T> {}
289