1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
use super::*;

/// A trait which indicates that a type is a `#[repr(transparent)]` wrapper
/// around the `Inner` value.
///
/// This allows safely copy transmuting between the `Inner` type and the
/// `TransparentWrapper` type. Functions like `wrap_{}` convert from the inner
/// type to the wrapper type and `peel_{}` functions do the inverse conversion
/// from the wrapper type to the inner type. We deliberately do not call the
/// wrapper-removing methods "unwrap" because at this point that word is too
/// strongly tied to the Option/ Result methods.
///
/// # Safety
///
/// The safety contract of `TransparentWrapper` is relatively simple:
///
/// For a given `Wrapper` which implements `TransparentWrapper<Inner>`:
///
/// 1. `Wrapper` must be a wrapper around `Inner` with an identical data
///    representations. This    either means that it must be a
///    `#[repr(transparent)]` struct which    contains a either a field of type
///    `Inner` (or a field of some other    transparent wrapper for `Inner`) as
///    the only non-ZST field.
///
/// 2. Any fields *other* than the `Inner` field must be trivially constructable
///    ZSTs, for example `PhantomData`, `PhantomPinned`, etc.
///
/// 3. The `Wrapper` may not impose additional alignment requirements over
///    `Inner`.
///     - Note: this is currently guaranteed by `repr(transparent)`, but there
///       have been discussions of lifting it, so it's stated here explicitly.
///
/// 4. All functions on `TransparentWrapper` **may not** be overridden.
///
/// ## Caveats
///
/// If the wrapper imposes additional constraints upon the inner type which are
/// required for safety, it's responsible for ensuring those still hold -- this
/// generally requires preventing access to instances of the inner type, as
/// implementing `TransparentWrapper<U> for T` means anybody can call
/// `T::cast_ref(any_instance_of_u)`.
///
/// For example, it would be invalid to implement TransparentWrapper for `str`
/// to implement `TransparentWrapper` around `[u8]` because of this.
///
/// # Examples
///
/// ## Basic
///
/// ```
/// use bytemuck::TransparentWrapper;
/// # #[derive(Default)]
/// # struct SomeStruct(u32);
///
/// #[repr(transparent)]
/// struct MyWrapper(SomeStruct);
///
/// unsafe impl TransparentWrapper<SomeStruct> for MyWrapper {}
///
/// // interpret a reference to &SomeStruct as a &MyWrapper
/// let thing = SomeStruct::default();
/// let inner_ref: &MyWrapper = MyWrapper::wrap_ref(&thing);
///
/// // Works with &mut too.
/// let mut mut_thing = SomeStruct::default();
/// let inner_mut: &mut MyWrapper = MyWrapper::wrap_mut(&mut mut_thing);
///
/// # let _ = (inner_ref, inner_mut); // silence warnings
/// ```
///
/// ## Use with dynamically sized types
///
/// ```
/// use bytemuck::TransparentWrapper;
///
/// #[repr(transparent)]
/// struct Slice<T>([T]);
///
/// unsafe impl<T> TransparentWrapper<[T]> for Slice<T> {}
///
/// let s = Slice::wrap_ref(&[1u32, 2, 3]);
/// assert_eq!(&s.0, &[1, 2, 3]);
///
/// let mut buf = [1, 2, 3u8];
/// let sm = Slice::wrap_mut(&mut buf);
/// ```
pub unsafe trait TransparentWrapper<Inner: ?Sized> {
  /// Convert the inner type into the wrapper type.
  #[inline]
  fn wrap(s: Inner) -> Self
  where
    Self: Sized,
    Inner: Sized,
  {
    // SAFETY: The unsafe contract requires that `Self` and `Inner` have
    // identical representations.
    unsafe { transmute!(s) }
  }

  /// Convert a reference to the inner type into a reference to the wrapper
  /// type.
  #[inline]
  fn wrap_ref(s: &Inner) -> &Self {
    unsafe {
      assert!(size_of::<*const Inner>() == size_of::<*const Self>());
      // A pointer cast doesn't work here because rustc can't tell that
      // the vtables match (because of the `?Sized` restriction relaxation).
      // A `transmute` doesn't work because the sizes are unspecified.
      //
      // SAFETY: The unsafe contract requires that these two have
      // identical representations.
      let inner_ptr = s as *const Inner;
      let wrapper_ptr: *const Self = transmute!(inner_ptr);
      &*wrapper_ptr
    }
  }

  /// Convert a mutable reference to the inner type into a mutable reference to
  /// the wrapper type.
  #[inline]
  fn wrap_mut(s: &mut Inner) -> &mut Self {
    unsafe {
      assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
      // A pointer cast doesn't work here because rustc can't tell that
      // the vtables match (because of the `?Sized` restriction relaxation).
      // A `transmute` doesn't work because the sizes are unspecified.
      //
      // SAFETY: The unsafe contract requires that these two have
      // identical representations.
      let inner_ptr = s as *mut Inner;
      let wrapper_ptr: *mut Self = transmute!(inner_ptr);
      &mut *wrapper_ptr
    }
  }

  /// Convert a slice to the inner type into a slice to the wrapper type.
  #[inline]
  fn wrap_slice(s: &[Inner]) -> &[Self]
  where
    Self: Sized,
    Inner: Sized,
  {
    unsafe {
      assert!(size_of::<*const Inner>() == size_of::<*const Self>());
      assert!(align_of::<*const Inner>() == align_of::<*const Self>());
      // SAFETY: The unsafe contract requires that these two have
      // identical representations (size and alignment).
      core::slice::from_raw_parts(s.as_ptr() as *const Self, s.len())
    }
  }

  /// Convert a mutable slice to the inner type into a mutable slice to the
  /// wrapper type.
  #[inline]
  fn wrap_slice_mut(s: &mut [Inner]) -> &mut [Self]
  where
    Self: Sized,
    Inner: Sized,
  {
    unsafe {
      assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
      assert!(align_of::<*mut Inner>() == align_of::<*mut Self>());
      // SAFETY: The unsafe contract requires that these two have
      // identical representations (size and alignment).
      core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Self, s.len())
    }
  }

  /// Convert the wrapper type into the inner type.
  #[inline]
  fn peel(s: Self) -> Inner
  where
    Self: Sized,
    Inner: Sized,
  {
    unsafe { transmute!(s) }
  }

  /// Convert a reference to the wrapper type into a reference to the inner
  /// type.
  #[inline]
  fn peel_ref(s: &Self) -> &Inner {
    unsafe {
      assert!(size_of::<*const Inner>() == size_of::<*const Self>());
      // A pointer cast doesn't work here because rustc can't tell that
      // the vtables match (because of the `?Sized` restriction relaxation).
      // A `transmute` doesn't work because the sizes are unspecified.
      //
      // SAFETY: The unsafe contract requires that these two have
      // identical representations.
      let wrapper_ptr = s as *const Self;
      let inner_ptr: *const Inner = transmute!(wrapper_ptr);
      &*inner_ptr
    }
  }

  /// Convert a mutable reference to the wrapper type into a mutable reference
  /// to the inner type.
  #[inline]
  fn peel_mut(s: &mut Self) -> &mut Inner {
    unsafe {
      assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
      // A pointer cast doesn't work here because rustc can't tell that
      // the vtables match (because of the `?Sized` restriction relaxation).
      // A `transmute` doesn't work because the sizes are unspecified.
      //
      // SAFETY: The unsafe contract requires that these two have
      // identical representations.
      let wrapper_ptr = s as *mut Self;
      let inner_ptr: *mut Inner = transmute!(wrapper_ptr);
      &mut *inner_ptr
    }
  }

  /// Convert a slice to the wrapped type into a slice to the inner type.
  #[inline]
  fn peel_slice(s: &[Self]) -> &[Inner]
  where
    Self: Sized,
    Inner: Sized,
  {
    unsafe {
      assert!(size_of::<*const Inner>() == size_of::<*const Self>());
      assert!(align_of::<*const Inner>() == align_of::<*const Self>());
      // SAFETY: The unsafe contract requires that these two have
      // identical representations (size and alignment).
      core::slice::from_raw_parts(s.as_ptr() as *const Inner, s.len())
    }
  }

  /// Convert a mutable slice to the wrapped type into a mutable slice to the
  /// inner type.
  #[inline]
  fn peel_slice_mut(s: &mut [Self]) -> &mut [Inner]
  where
    Self: Sized,
    Inner: Sized,
  {
    unsafe {
      assert!(size_of::<*mut Inner>() == size_of::<*mut Self>());
      assert!(align_of::<*mut Inner>() == align_of::<*mut Self>());
      // SAFETY: The unsafe contract requires that these two have
      // identical representations (size and alignment).
      core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Inner, s.len())
    }
  }
}

unsafe impl<T> TransparentWrapper<T> for core::num::Wrapping<T> {}