google / google/zerocopy

Encode size and alignment in the type system

Open
#1,316 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2.6k
Forks
179
Avg merge
1d 19h
Merged PRs (30d)
29

Description

*Any design for this issue will interact with other issues tracked by #885; make sure to read that issue when tackling this one.*

Without [generic_const_exprs](https://github.com/rust-lang/rust/issues/76560), we can't use `size_of::()` or `align_of::()` in a generic context. We have many use cases for these, so it would be good to work around the issue with a sort of polyfill.

In general, we'd like to be able to express in the type system:
- `size_of::() == size_of::()`
- `align_of::() >= align_of::()` (useful for reference transmutations from `T` to `U`)
- `size_of::() == N`
- `align_of::() >= N` or `<= N` (to support #280)

## API

The most obvious approach is to add machinery to `KnownLayout`, although we need this machinery to *not* rely on const generics (like the associated `LAYOUT` type currently does), so it would need to be a true type-level representation. It might be the case that:
- There are types we want to support which `KnownLayout` can't
- There are types which `KnownLayout` currently supports which can't support this approach

Thus, we may need to introduce a separate trait or traits.

Given that the knowledge is now encoded in the type system, we need some way of expressing bounds. In other words, we need some sort of:
- `T: SizeEq`
- `T: AlignGtEq`
- `T: SizeEqConst`
- `T: AlignGtEqConst`

These could either be blanket impls in terms of `KnownLayout`, or be separate from `KnownLayout` entirely (and might need to be derived).

---

Merging #125 into this:

> This is a half-baked idea, and it requires the unstable [associated_const_equality](https://github.com/rust-lang/rust/issues/92827) feature. Also, the `AlignedTo` impls don't currently work thanks to https://github.com/rust-lang/rust/issues/103292.
>
> ```rust
> trait Size {
> const SIZE: usize;
> }
>
> impl Size for T {
> const SIZE: usize = core::mem::size_of::();
> }
>
> trait Align {
> const ALIGN: usize;
> }
>
> impl Align for T {
> const ALIGN: usize = core::mem::align_of::();
> }
>
> trait Zst {}
>
> impl> Zst for T {}
>
> trait SameSizeAs {}
>
> impl, U: Size> SameSizeAs for T {}
>
> trait AlignedTo {}
>
> impl, U: Align> AlignedTo for T {}
> impl, U: Align> AlignedTo for T {}
> impl, U: Align> AlignedTo for T {}
> impl, U: Align> AlignedTo for T {}
> impl, U: Align> AlignedTo for T {}
> impl, U: Align> AlignedTo for T {}
> ```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.