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:
- by value, using
getorinto_inner - by reference inside of a callback, using
update - fallibly by reference, using
try_derefortry_deref_mut; these can fail if theUnaligndoes not satisfyT's alignment requirement at runtime - unsafely by reference, using
deref_uncheckedorderef_mut_unchecked; it is the caller's responsibility to ensure that theUnalignsatisfiesT's alignment requirement - (where
T: Unaligned) infallibly by reference, usingDeref::dereforDerefMut::deref_mut
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 *;
# use *;
# ;
#
let bytes = &;
// PANICS: Guaranteed not to panic because `bytes` is of the right
// length, has the right contents, and `EthernetFrame` has no
// alignment requirement.
let packet = try_ref_from_bytes.unwrap;
assert_eq!;
assert_eq!;
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) -> TConsumes
self, returning the innerT.fn try_deref(&self) -> Result<&T, AlignmentError<&Self, T>>Attempts to return a reference to the wrapped
T, failing ifselfis not properly aligned.If
selfdoes not satisfyalign_of::<T>(), thentry_derefreturnsErr.If
T: Unaligned, thenUnalign<T>implementsDeref, and callers may preferDeref::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 ifselfis not properly aligned.If
selfdoes not satisfyalign_of::<T>(), thentry_derefreturnsErr.If
T: Unaligned, thenUnalign<T>implementsDerefMut, and callers may preferDerefMut::deref_mut, which is infallible.const unsafe fn deref_unchecked(&self) -> &TReturns a reference to the wrapped
Twithout checking alignment.If
T: Unaligned, thenUnalign<T>implements[Deref], and callers may preferDeref::deref, which is safe.Safety
The caller must guarantee that
selfsatisfiesalign_of::<T>().unsafe fn deref_mut_unchecked(&mut self) -> &mut TReturns a mutable reference to the wrapped
Twithout checking alignment.If
T: Unaligned, thenUnalign<T>implements[DerefMut], and callers may preferDerefMut::deref_mut, which is safe.Safety
The caller must guarantee that
selfsatisfiesalign_of::<T>().const fn get_ptr(&self) -> *const TGets 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 ofget_ptrwill 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 asread_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, preferget_mut_ptrinstead.fn get_mut_ptr(&mut self) -> *mut TGets 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 ofget_ptrwill 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 asread_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) -> OUpdates the inner
Tby calling a function on it.If
T: Unaligned, thenUnalign<T>implementsDerefMut, 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
Tmay not be aligned, it would not be sound to invokefon it directly. Instead,updatemoves it into a properly-aligned location in the local stack frame, callsfon it, and then moves it back to its original location inself.
impl<T: Copy> Unalign<T>
fn get(&self) -> TGets 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) -> TReturns the argument unchanged.
impl<T, U> Into<U> for Unalign<T>
where
U: From<T>,
fn into(self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses 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>