Trait bytemuck::TransparentWrapper
source · pub unsafe trait TransparentWrapper<Inner: ?Sized> {
// Provided methods
fn wrap(s: Inner) -> Self
where Self: Sized,
Inner: Sized { ... }
fn wrap_ref(s: &Inner) -> &Self { ... }
fn wrap_mut(s: &mut Inner) -> &mut Self { ... }
fn wrap_slice(s: &[Inner]) -> &[Self]
where Self: Sized,
Inner: Sized { ... }
fn wrap_slice_mut(s: &mut [Inner]) -> &mut [Self]
where Self: Sized,
Inner: Sized { ... }
fn peel(s: Self) -> Inner
where Self: Sized,
Inner: Sized { ... }
fn peel_ref(s: &Self) -> &Inner { ... }
fn peel_mut(s: &mut Self) -> &mut Inner { ... }
fn peel_slice(s: &[Self]) -> &[Inner]
where Self: Sized,
Inner: Sized { ... }
fn peel_slice_mut(s: &mut [Self]) -> &mut [Inner]
where Self: Sized,
Inner: Sized { ... }
}Expand description
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>:
-
Wrappermust be a wrapper aroundInnerwith an identical data representations. This either means that it must be a#[repr(transparent)]struct which contains a either a field of typeInner(or a field of some other transparent wrapper forInner) as the only non-ZST field. -
Any fields other than the
Innerfield must be trivially constructable ZSTs, for examplePhantomData,PhantomPinned, etc. (When derivingTransparentWrapperon a type with ZST fields, the ZST fields must beZeroable). -
The
Wrappermay not impose additional alignment requirements overInner.- Note: this is currently guaranteed by
repr(transparent), but there have been discussions of lifting it, so it’s stated here explicitly.
- Note: this is currently guaranteed by
-
All functions on
TransparentWrappermay 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;
#[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);
§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);§Deriving
When deriving, the non-wrapped fields must uphold all the normal
requirements, and must also be Zeroable.
use bytemuck::TransparentWrapper;
use std::marker::PhantomData;
#[derive(TransparentWrapper)]
#[repr(transparent)]
#[transparent(usize)]
struct Wrapper<T: ?Sized>(usize, PhantomData<T>); // PhantomData<T> implements Zeroable for all THere, an error will occur, because MyZst does not implement Zeroable.
use bytemuck::TransparentWrapper;
struct MyZst;
#[derive(TransparentWrapper)]
#[repr(transparent)]
#[transparent(usize)]
struct Wrapper(usize, MyZst); // MyZst does not implement ZeroableProvided Methods§
sourcefn wrap_ref(s: &Inner) -> &Self
fn wrap_ref(s: &Inner) -> &Self
Convert a reference to the inner type into a reference to the wrapper type.
sourcefn wrap_mut(s: &mut Inner) -> &mut Self
fn wrap_mut(s: &mut Inner) -> &mut Self
Convert a mutable reference to the inner type into a mutable reference to the wrapper type.
sourcefn wrap_slice(s: &[Inner]) -> &[Self]
fn wrap_slice(s: &[Inner]) -> &[Self]
Convert a slice to the inner type into a slice to the wrapper type.
sourcefn wrap_slice_mut(s: &mut [Inner]) -> &mut [Self]
fn wrap_slice_mut(s: &mut [Inner]) -> &mut [Self]
Convert a mutable slice to the inner type into a mutable slice to the wrapper type.
sourcefn peel_ref(s: &Self) -> &Inner
fn peel_ref(s: &Self) -> &Inner
Convert a reference to the wrapper type into a reference to the inner type.
sourcefn peel_mut(s: &mut Self) -> &mut Inner
fn peel_mut(s: &mut Self) -> &mut Inner
Convert a mutable reference to the wrapper type into a mutable reference to the inner type.
sourcefn peel_slice(s: &[Self]) -> &[Inner]
fn peel_slice(s: &[Self]) -> &[Inner]
Convert a slice to the wrapped type into a slice to the inner type.