Struct Unalign

#[repr(C, packed(1))]
pub struct Unalign<T>(/* private field */);

A type with no alignment requirement.

An Unalign wraps a T, removing any alignment requirement. Unalign<T> has the same size and bit validity as T, but not necessarily the same alignment or ABI. This is useful if a type with an alignment requirement needs to be read from a chunk of memory which provides no alignment guarantees.

Since Unalign has no alignment requirement, the inner T may not be properly aligned in memory. There are five ways to access the inner T:

Example

In this example, we need EthernetFrame to have no alignment requirement - and thus implement Unaligned. EtherType is #[repr(u16)] and so cannot implement Unaligned. We use Unalign to relax EtherType's alignment requirement so that EthernetFrame has no alignment requirement and can implement Unaligned.

use zerocopy::*;
# use zerocopy_derive::*;
# #[derive(FromBytes, KnownLayout, Immutable, Unaligned)] #[repr(C)] struct Mac([u8; 6]);

# #[derive(PartialEq, Copy, Clone, Debug)]
#[derive(TryFromBytes, KnownLayout, Immutable)]
#[repr(u16)]
enum EtherType {
    Ipv4 = 0x0800u16.to_be(),
    Arp = 0x0806u16.to_be(),
    Ipv6 = 0x86DDu16.to_be(),
    # /*
    ...
    # */
}

#[derive(TryFromBytes, KnownLayout, Immutable, Unaligned)]
#[repr(C)]
struct EthernetFrame {
    src: Mac,
    dst: Mac,
    ethertype: Unalign<EtherType>,
    payload: [u8],
}

let bytes = &[
    # 0, 1, 2, 3, 4, 5,
    # 6, 7, 8, 9, 10, 11,
    # /*
    ...
    # */
    0x86, 0xDD,            // EtherType
    0xDE, 0xAD, 0xBE, 0xEF // Payload
][..];

// PANICS: Guaranteed not to panic because `bytes` is of the right
// length, has the right contents, and `EthernetFrame` has no
// alignment requirement.
let packet = EthernetFrame::try_ref_from_bytes(&bytes).unwrap();

assert_eq!(packet.ethertype.get(), EtherType::Ipv6);
assert_eq!(packet.payload, [0xDE, 0xAD, 0xBE, 0xEF]);

Safety

Unalign<T> is guaranteed to have the same size and bit validity as T, and to have UnsafeCells covering the same byte ranges as T. Unalign<T> is guaranteed to have alignment 1.

Implementations

impl<T> Unalign<T>

const fn new(val: T) -> Unalign<T>

Constructs a new Unalign.

const fn into_inner(self) -> T

Consumes self, returning the inner T.

fn try_deref(&self) -> Result<&T, AlignmentError<&Self, T>>

Attempts to return a reference to the wrapped T, failing if self is not properly aligned.

If self does not satisfy align_of::<T>(), then try_deref returns Err.

If T: Unaligned, then Unalign<T> implements Deref, and callers may prefer Deref::deref, which is infallible.

fn try_deref_mut(&mut self) -> Result<&mut T, AlignmentError<&mut Self, T>>

Attempts to return a mutable reference to the wrapped T, failing if self is not properly aligned.

If self does not satisfy align_of::<T>(), then try_deref returns Err.

If T: Unaligned, then Unalign<T> implements DerefMut, and callers may prefer DerefMut::deref_mut, which is infallible.

const unsafe fn deref_unchecked(&self) -> &T

Returns a reference to the wrapped T without checking alignment.

If T: Unaligned, then Unalign<T> implements[ Deref], and callers may prefer Deref::deref, which is safe.

Safety

The caller must guarantee that self satisfies align_of::<T>().

unsafe fn deref_mut_unchecked(&mut self) -> &mut T

Returns a mutable reference to the wrapped T without checking alignment.

If T: Unaligned, then Unalign<T> implements[ DerefMut], and callers may prefer DerefMut::deref_mut, which is safe.

Safety

The caller must guarantee that self satisfies align_of::<T>().

const fn get_ptr(&self) -> *const T

Gets an unaligned raw pointer to the inner T.

Safety

The returned raw pointer is not necessarily aligned to align_of::<T>(). Most functions which operate on raw pointers require those pointers to be aligned, so calling those functions with the result of get_ptr will result in undefined behavior if alignment is not guaranteed using some out-of-band mechanism. In general, the only functions which are safe to call with this pointer are those which are explicitly documented as being sound to use with an unaligned pointer, such as read_unaligned.

Even if the caller is permitted to mutate self (e.g. they have ownership or a mutable borrow), it is not guaranteed to be sound to write through the returned pointer. If writing is required, prefer get_mut_ptr instead.

fn get_mut_ptr(&mut self) -> *mut T

Gets an unaligned mutable raw pointer to the inner T.

Safety

The returned raw pointer is not necessarily aligned to align_of::<T>(). Most functions which operate on raw pointers require those pointers to be aligned, so calling those functions with the result of get_ptr will result in undefined behavior if alignment is not guaranteed using some out-of-band mechanism. In general, the only functions which are safe to call with this pointer are those which are explicitly documented as being sound to use with an unaligned pointer, such as read_unaligned.

fn set(&mut self, t: T)

Sets the inner T, dropping the previous value.

fn update<O, F: FnOnce(&mut T) -> O>(&mut self, f: F) -> O

Updates the inner T by calling a function on it.

If T: Unaligned, then Unalign<T> implements DerefMut, and that impl should be preferred over this method when performing updates, as it will usually be faster and more ergonomic.

For large types, this method may be expensive, as it requires copying 2 * size_of::<T>() bytes. [1]

[1] Since the inner T may not be aligned, it would not be sound to invoke f on it directly. Instead, update moves it into a properly-aligned location in the local stack frame, calls f on it, and then moves it back to its original location in self.

impl<T: Copy> Unalign<T>

fn get(&self) -> T

Gets a copy of the inner T.

Trait Implementations

impl<T> FromBytes for Unalign<T> where T: FromBytes,

impl<T> FromZeros for Unalign<T> where T: FromZeros,

impl<T> Immutable for Unalign<T> where T: Immutable,

impl<T> IntoBytes for Unalign<T> where T: IntoBytes,

impl<T> KnownLayout for Unalign<T>

type PointerMetadata = ();

impl<T> TryFromBytes for Unalign<T> where T: TryFromBytes,

impl<T> Unaligned for Unalign<T>

impl<T: Copy> Clone for Unalign<T>

fn clone(&self) -> Unalign<T>

impl<T: Copy> Copy for Unalign<T>

impl<T: Default> Default for Unalign<T>

fn default() -> Unalign<T>

impl<T: Unaligned + Debug> Debug for Unalign<T>

fn fmt(&self, f: &mut Formatter<'_>) -> Result

impl<T: Unaligned + Display> Display for Unalign<T>

fn fmt(&self, f: &mut Formatter<'_>) -> Result

impl<T: Unaligned + Eq> Eq for Unalign<T>

impl<T: Unaligned + Hash> Hash for Unalign<T>

fn hash<H>(&self, state: &mut H)
where
    H: Hasher,

impl<T: Unaligned + Ord> Ord for Unalign<T>

fn cmp(&self, other: &Unalign<T>) -> Ordering

impl<T: Unaligned + PartialEq> PartialEq for Unalign<T>

fn eq(&self, other: &Unalign<T>) -> bool

impl<T: Unaligned + PartialOrd> PartialOrd for Unalign<T>

fn partial_cmp(&self, other: &Unalign<T>) -> Option<Ordering>

impl<T: Unaligned> Deref for Unalign<T>

type Target = T;
fn deref(&self) -> &T

impl<T: Unaligned> DerefMut for Unalign<T>

fn deref_mut(&mut self) -> &mut T

Auto Trait Implementations

impl<T> Freeze for Unalign<T> where T: Freeze,

impl<T> RefUnwindSafe for Unalign<T> where T: RefUnwindSafe,

impl<T> Send for Unalign<T> where T: Send,

impl<T> Sync for Unalign<T> where T: Sync,

impl<T> Unpin for Unalign<T> where T: Unpin,

impl<T> UnsafeUnpin for Unalign<T> where T: UnsafeUnpin,

impl<T> UnwindSafe for Unalign<T> where T: UnwindSafe,

Blanket Implementations

impl<P, T> Receiver for Unalign<T> where P: Deref<Target = T> + ?Sized, T: ?Sized,

type Target = T;

impl<T> Any for Unalign<T> where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for Unalign<T> where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for Unalign<T> where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> CloneToUninit for Unalign<T> where T: Clone,

unsafe fn clone_to_uninit(&self, dest: *mut u8)

impl<T> From<T> for Unalign<T>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T, U> Into<U> for Unalign<T> where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for Unalign<T> where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for Unalign<T> where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>