Missed layout optimization

And this can be mostly resolved by the following:

  • introduce stride_of and stride_of_val which act identically to today's size_of and size_of_val
  • enable types to opt in to size < stride with an attribute like #[repr(size_not_aligned)] or something
  • possibly make that default in some future edition

We change the behavior of size_of and add a new function to get the old behavior. This allows old code using size_of to transparently work.

Would need to consider how Layout would need to change. And if someone is assuming size_of<[T; N]> == size_of<T> * N in unsafe code that would be a problem.

I ran into the same problem a while ago and made a crate struct-pad to solve it.


Bar gets optimized because the c byte has two valid values (0 and 1) and 254 invalid values, so Option gets to pick any one of the invalid values for its use, and rely on it not being overwritten by writing a valid bool because a valid bool can never have anything but 0 or 1 there

Shouldn't this rewrite the niche?

let mut maybe_bar = Some(Bar { a: 1, b: 2, c: true });
let bar = Bar { a: 1, b: 2, c: true };
if let Some(barmut) = maybe_bar.as_mut() {
    std::mem::replace(barmut, bar);

It does require the niche. But the bit representation of Some(Bar) and Bar are identical (the niche bits in the bool are exactly 0 for both). So everything works as intended.

Rust also guarantees that arrays are size_of::<T>() * N bytes, with the nth element being at offset n * size_of::<T>().


1 Like

That's really cool and would have been really useful in something I was working on recently. Even for arrays it is useful to have strides (e.g., to work on columns of a row-major matrix) and I think library-based approaches such as ndarray feel tacked-on. But it's probably horrible for optimization if the compiler can't vectorize loads from a &[T] (or has to emit two versions of a function).

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.