-
Notifications
You must be signed in to change notification settings - Fork 142
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, 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:
size_of::<T>() == size_of::<U>()align_of::<T>() >= align_of::<U>()(useful for reference transmutations fromTtoU)size_of::<T>() == Nalign_of::<T>() >= Nor<= N(to support Support eliding alignment check when reading from aligned buffer #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
KnownLayoutcan't - There are types which
KnownLayoutcurrently 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
AlignedToimpls 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 {}