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.
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.
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).