macro_rules! try_transmute_ref { ($e:expr) => { ... }; }
Expand description
Conditionally transmutes a mutable or immutable reference of one type to an immutable reference of another type of the same size and compatible alignment.
This macro behaves like an invocation of this function:
fn try_transmute_ref<Src, Dst>(src: &Src) -> Result<&Dst, ValidityError<&Src, Dst>>
where
Src: IntoBytes + Immutable,
Dst: TryFromBytes + 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
// 0u8 → bool = false
assert_eq!(try_transmute_ref!(&0u8), Ok(&false));
// 1u8 → bool = true
assert_eq!(try_transmute_ref!(&1u8), Ok(&true));
// 2u8 → bool = error
assert!(matches!(
try_transmute_ref!(&2u8),
Result::<&bool, _>::Err(ValidityError { .. })
));
§Alignment increase error message
Because of limitations on macros, the error message generated when
try_transmute_ref!
is used to transmute from a type of lower alignment to
a type of higher alignment is somewhat confusing. For example, the following
code:
let increase_alignment: Result<&u16, _> = zerocopy::try_transmute_ref!(&[0u8; 2]);
…generates the following error:
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> example.rs:1:47
|
1 | let increase_alignment: Result<&u16, _> = zerocopy::try_transmute_ref!(&[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 `zerocopy::try_transmute_ref` (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>()
.