Encode size and alignment in the type system
- 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
Assessment
This issue has not been assessed yet.