Okay so let me try to see whether I puzzled this together correctly… took me a while.^^
You are talking about the iterator over slices of ZST types. That iterator currently internally works by bumping up a pointer by 1 until we reached a pre-computed end pointer. (That’s a special case; usually it bumps up by the size but with a ZST that would literally go nowhere.) Now if we are to bump up by alignment (rather than 1), then we get in trouble if a slice is so big that this makes the addition overflow.
On a slightly higher level, the trouble is that ZSTs are the only types for which we can have align > size.
Is that what you are talking about?
However, notice that the slice iterator currently already yields just a stream of 0x1 [^1] (ignoring alignment). It could instead yield a stream of aligned pointers. That would of course still leave the internal pointer used by the iterator unaligned; maybe that one should be a raw pointer and not a reference. (Maybe it already is?)
[^1] Also see https://github.com/rust-lang/rust/issues/42789.
Speaking of raw pointers, @eddyb mentioned that LLVM may rely on pointers being aligned in general, not just in some well-controlled places. It may, for example, optimize away bit operations on pointers that become NOPs for aligned pointers. Gathering some evidence around this would be very interesting, because Rust allows creating unaligned raw pointers in safe code, and it IMHO be a severe bug if LLVM optimized things assuming that the pointers are aligned.
In fact, I just realized (by reading some miri testcases) Rust allows creating and using unaligned pointers in safe code…
#[repr(packed)]
struct Foo {
x: u16,
y: u32,
}
fn main() {
let mut b = Box::new(Foo { x: 0, y: 0 });
let y = &mut b.y;
println!("{}", *y);
*y = 13;
println!("{}", *y);
println!("{}", (y as *const _ as usize) % 4);
}
This prints 0 13 2 on playpen.
I am… confused now. It doesn’t seem like Rust can make any assumptions whatsoever about the alignment even of safe references, can it? Does it?