Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encode size and alignment in the type system #1316

Open
joshlf opened this issue May 19, 2024 · 1 comment
Open

Encode size and alignment in the type system #1316

joshlf opened this issue May 19, 2024 · 1 comment

Comments

@joshlf
Copy link
Member

joshlf commented May 19, 2024

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, we can't use size_of::<T>() or align_of::<T>() 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:

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<U>
  • T: AlignGtEq<U>
  • T: SizeEqConst<N>
  • T: AlignGtEqConst<N>

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 feature. Also, the AlignedTo impls don't currently work thanks to rust-lang/rust#103292.

trait Size {
    const SIZE: usize;
}

impl<T> Size for T {
    const SIZE: usize = core::mem::size_of::<T>();
}

trait Align {
    const ALIGN: usize;
}

impl<T> Align for T {
    const ALIGN: usize = core::mem::align_of::<T>();
}

trait Zst {}

impl<T: Size<SIZE = 0>> Zst for T {}

trait SameSizeAs<T> {}

impl<const SIZE: usize, T: Size<SIZE = { SIZE }>, U: Size<SIZE = { SIZE }>> SameSizeAs<U> for T {}

trait AlignedTo<T> {}

impl<T: Align<ALIGN = 1>, U: Align<ALIGN = 1>> AlignedTo<U> for T {}
impl<T: Align<ALIGN = 2>, U: Align<ALIGN = 2>> AlignedTo<U> for T {}
impl<T: Align<ALIGN = 2>, U: Align<ALIGN = 1>> AlignedTo<U> for T {}
impl<T: Align<ALIGN = 4>, U: Align<ALIGN = 4>> AlignedTo<U> for T {}
impl<T: Align<ALIGN = 4>, U: Align<ALIGN = 2>> AlignedTo<U> for T {}
impl<T: Align<ALIGN = 4>, U: Align<ALIGN = 1>> AlignedTo<U> for T {}
@kupiakos
Copy link
Contributor

I have some typenum-like scratch code here and here as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants