You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Any design for this issue will interact with other issues tracked by #885; make sure to read that issue when tackling this one.
Currently, we special-case types with alignment 1 by allowing them to implement the Unaligned trait, and use that trait to elide an alignment check when attempting to read a type from a [u8], which provides no alignment guarantees (e.g., Ref constructors with unaligned in their name).
If we add an Align type, it will be possible to express the type of a [u8] which has an alignment guarantee greater than 1. It would be useful if we could also elide alignment checks when parsing non-Unaligned types from these aligned buffers so long as the buffer's alignment is at least as large as the type's alignment.
This could potentially result in more optimal code for users like packet-formats, which currently have to assume that all loads may be unaligned (e.g. using unaligned types from the byteorder module).
Alignment reasoning
In general, we need the ability to understand that &Src -> &Dst doesn't require an alignment check. This could either be thanks to knowing that align_of::<Src>() >= align_of::<Dst>() (#1316), or by forcing it using an Align type (#249).
Use in buffers
I can imagine two shapes for this API:
Buffer returned by value
For example, Ref and FromBytes methods often consume a &[u8] and return (&T, &[u8]) (or a B: ByteSlice instead of &[u8]). We could imagine instead requiring the input be Align<[u8], {align_of::<T>()}> and returning (&T, Align<[u8], {align_of::<T>()}>)
Buffer alignment unmodified by &mut methods
If we also support a trait or traits in the style of packet::BufferView, we could imagine adding an alignment invariant:
traitBuffer<constALIGN:usize>{// TODO: How to express in the type system that `n % ALIGN == 0`? Or maybe// just validate at runtime?fntake_bytes_front(&mutself,n:usize) -> Option<&Align<[u8],{ALIGN}>>;// Alternatively, using a `ByteArray` API a la #248:fn take_bytes_front<T>(&mutself) -> Option<&Align<ByteArray<T>,{ALIGN}>>wheresize_of::<ByteArray<T>>() % ALIGN == 0;// TODO: How to express this in the type system?// Since `align_of::<T>() <= N`, this can return only `SizeError`.fntake_obj_front<T:FromBytes>(&mutself) -> Result<&T,SizeError>whereT:AlignLtEq<{N}>,// Supported by #1316size_of::<T>() % ALIGN == 0;// TODO: How to express this in the type system?{
...
}}
take_bytes_front requires the alignment as its precondition, and preserves it as its post-condition.
The text was updated successfully, but these errors were encountered:
Any design for this issue will interact with other issues tracked by #885; make sure to read that issue when tackling this one.
Currently, we special-case types with alignment 1 by allowing them to implement the
Unaligned
trait, and use that trait to elide an alignment check when attempting to read a type from a[u8]
, which provides no alignment guarantees (e.g.,Ref
constructors withunaligned
in their name).If we add an
Align
type, it will be possible to express the type of a[u8]
which has an alignment guarantee greater than 1. It would be useful if we could also elide alignment checks when parsing non-Unaligned
types from these aligned buffers so long as the buffer's alignment is at least as large as the type's alignment.This could potentially result in more optimal code for users like packet-formats, which currently have to assume that all loads may be unaligned (e.g. using unaligned types from the
byteorder
module).Alignment reasoning
In general, we need the ability to understand that
&Src -> &Dst
doesn't require an alignment check. This could either be thanks to knowing thatalign_of::<Src>() >= align_of::<Dst>()
(#1316), or by forcing it using anAlign
type (#249).Use in buffers
I can imagine two shapes for this API:
Buffer returned by value
For example,
Ref
andFromBytes
methods often consume a&[u8]
and return(&T, &[u8])
(or aB: ByteSlice
instead of&[u8]
). We could imagine instead requiring the input beAlign<[u8], {align_of::<T>()}>
and returning(&T, Align<[u8], {align_of::<T>()}>)
Buffer alignment unmodified by
&mut
methodsIf we also support a trait or traits in the style of
packet::BufferView
, we could imagine adding an alignment invariant:take_bytes_front
requires the alignment as its precondition, and preserves it as its post-condition.The text was updated successfully, but these errors were encountered: