macro_rules! transmute_mut { ($e:expr) => { ... }; }
Expand description
Safely transmutes a mutable reference of one type to a mutable reference of another type of the same size and compatible alignment.
This macro behaves like an invocation of this function:
const fn transmute_mut<'src, 'dst, Src, Dst>(src: &'src mut Src) -> &'dst mut Dst
where
'src: 'dst,
Src: FromBytes + IntoBytes + Immutable,
Dst: FromBytes + IntoBytes + Immutable,
size_of::<Src>() == size_of::<Dst>(),
align_of::<Src>() >= align_of::<Dst>(),
{
...
}
However, unlike a function, this macro can only be invoked when the types of
Src
and Dst
are completely concrete. The types Src
and Dst
are
inferred from the calling context; they cannot be explicitly specified in
the macro invocation.
§Examples
let mut one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
let two_dimensional: &mut [[u8; 4]; 2] = transmute_mut!(&mut one_dimensional);
assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);
two_dimensional.reverse();
assert_eq!(one_dimensional, [4, 5, 6, 7, 0, 1, 2, 3]);
§Use in const
contexts
This macro can be invoked in const
contexts.
§Alignment increase error message
Because of limitations on macros, the error message generated when
transmute_mut!
is used to transmute from a type of lower alignment to a
type of higher alignment is somewhat confusing. For example, the following
code:
const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
…generates the following error:
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> src/lib.rs:1524:34
|
5 | const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: source type: `AlignOf<[u8; 2]>` (8 bits)
= note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
= note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
This is saying that max(align_of::<T>(), align_of::<U>()) != align_of::<T>()
, which is equivalent to align_of::<T>() < align_of::<U>()
.