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`: /// /// 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. (When deriving /// `TransparentWrapper` on a type with ZST fields, the ZST fields must be /// [`Zeroable`]). /// /// 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 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 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]); /// /// unsafe impl TransparentWrapper<[T]> for Slice {} /// /// 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); /// ``` /// /// ## Deriving /// /// When deriving, the non-wrapped fields must uphold all the normal requirements, /// and must also be `Zeroable`. /// #[cfg_attr(feature = "derive", doc = "```")] #[cfg_attr( not(feature = "derive"), doc = "```ignore // This example requires the `derive` feature." )] /// use bytemuck::TransparentWrapper; /// use std::marker::PhantomData; /// /// #[derive(TransparentWrapper)] /// #[repr(transparent)] /// #[transparent(usize)] /// struct Wrapper(usize, PhantomData); // PhantomData implements Zeroable for all T /// ``` /// /// Here, an error will occur, because `MyZst` does not implement `Zeroable`. /// #[cfg_attr(feature = "derive", doc = "```compile_fail")] #[cfg_attr( not(feature = "derive"), doc = "```ignore // This example requires the `derive` feature." )] /// use bytemuck::TransparentWrapper; /// struct MyZst; /// /// #[derive(TransparentWrapper)] /// #[repr(transparent)] /// #[transparent(usize)] /// struct Wrapper(usize, MyZst); // MyZst does not implement Zeroable /// ``` pub unsafe trait TransparentWrapper { /// 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 TransparentWrapper for core::num::Wrapping {}