fn aligned_to(bytes: &[u8], align: usize) -> bool {
(bytes as *const _ as *const () as usize) % align == 0
}
I'd like to make it a const fn, but if I just do that without changing the implementation, the compiler complains:
error: pointers cannot be cast to integers during const eval
--> src/lib.rs:1636:5
|
1636 | (bytes as *const _ as *const () as usize) % align == 0
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: at compile-time, pointers do not have an integer value
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
Is there a different way to implement the same API that only uses const-safe operations? I can't figure out a way.
You definitely won't be able to do it using arithmetic, since addresses don't exist at const-evaluation time, but there are operations specifically for alignment available. Unfortunately, none of them are stably const.
The one which is exactly what you want is pointer::is_aligned_to but that's not stable and not const. pointer::align_offset is unstably const, but apparently that's because it's allowed to fail and always fails in const eval.
I imagine that if you want to achieve this you'll have to make a proposal for the compiler to support it, with a use case to justify it. Right now, I would expect that a const &[u8] simply does not have an alignment — its address is abstract and, if it persists through to run time, it could in principle be placed in memory with any alignment.