Skip to content

Encode size and alignment in the type system #1316

@joshlf

Description

@joshlf

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 {}

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions