zerocopy

Macro transmute_mut

Source
macro_rules! transmute_mut {
    ($e:expr) => { ... };
}
Expand description

Safely transmutes a mutable reference of one type to an mutable reference of another type of the same size.

The expression $e must have a concrete type, &mut T, where T: Sized + AsBytes. The transmute_mut! expression must also have a concrete type, &mut U (U is inferred from the calling context), where U: Sized + FromBytes. It must be the case that align_of::<T>() >= align_of::<U>().

The lifetime of the input type, &mut T, must be the same as or outlive the lifetime of the output type, &mut U.

§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]);

§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>().