Pod & Packed traits
Nobody has claimed this yet.
- Dominant language
- Markdown
- Stars
- 6.6k
- Forks
- 1.7k
- Avg merge
- 16h 14m
- Merged PRs (30d)
- 1
Description
I'm proposing adding Pod and Packed traits and a write_initialized intrinsic to make it easier to work with structured low-level APIs.
Previous discussions
A sized type T is Pod if any [u8; sizeof(T)] can safely be transmuted to T.
A (possibly unsized) object is Pod if any byte in its object representation can safely be overwritten by any other byte.
All integer types are Pod. All raw pointers to sized types are Pod. Arrays of Pod types are Pod. Tuples, structs and unions which contain only Pod types and which do not have invariants are Pod.
A sized type T is Packed if any object of type T can safely be transmuted to [u8; sizeof(T)].
A (possibly unsized) object is Pod if any byte in its object representation can safely be read as an u8.
All integer types are Packed. All raw pointers on currently supported platforms are Packed. Arrays of of Packed types are Packed. Whether tuples, structs and unions are Packed depends on their contents.
A Packed trait cannot be implemented safely outside the compiler.
Pod and Packed traits make it possible to write safe APIs that are useful in systems programming. For example:
fn pod_zeroed<T: Pod>() -> T;
// Err if sizeof(U) != sizeof(T)
fn pod_read<T: Pod, U: Packed + ?Sized>(u: &U) -> Result<T>;
// Err if sizeof(U) < sizeof(T)
fn pod_read_init<T: Pod, U: Packed + ?Sized>(u: &U) -> Result<T>;
// Err if sizeof(U) is not a multiple of sizeof(T)
fn pod_iter<T: Pod, U: Packed + ?Sized>(u: &U) -> Result<impl Iterator<Item = T>>;
// Err if sizeof(U) != sizeof(T)
fn pod_write<T: Pod + ?Sized, U: Packed + ?Sized>(u: &U, t: &mut MaybeUninit<T>) -> Result<()>;
Pod and Packed do not cover all use cases that deal with transmuting between bytes and objects. For example, it would be useful if the compiler provided the following intrinsic:
/// Overwrites `t` with `u`, replacing all padding bits of `U` by an unspecified bit pattern.
/// Err if sizeof(u) != sizeof(T).
fn write_initialized<T: Pod + ?Sized, U: ?Sized>(u: &U, t: &mut MaybeUninit<T>) -> Result<()>;
This would cover the usecase of writing data structures with padding bytes into memory.
Both Packed and Pod would not be auto-traits. Like Copy, every type has to opt into being Pod or Packed. Like Copy the compiler would verify at compile time that
- types implementing
Podonly contain otherPodtypes recursively - types implementing
Packedonly contain otherPackedtypes and do not have padding bits
I assume that Packed would be more controversial that Pod due to its platform dependence.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the proposed Pod and Packed trait definitions and the write_initialized intrinsic in the issue body, then review RFC pull requests 1387 and 936 for prior discussion. This is an RFC design task rather than a localized implementation; done means reaching an accepted design and implementation plan for the traits and intrinsic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100