generic-array
generic-array copied to clipboard
Unchecked versions of GenericArray::from_[mut_]slice
Minor point, but would it be possible to expose an unsafe version of these functions that doesn't perform any length-check?
Not exactly ergonomic, but you could do something like this in your own code where necessary:
use generic_array::{GenericArray, typenum::{U24, Unsigned}};
pub fn from_mut_slice(x: &mut [u8]) -> &mut GenericArray<u8, U24> {
if x.len() != U24::USIZE {
unsafe { std::hint::unreachable_unchecked() }
}
GenericArray::from_mut_slice(x)
}
Additional notes based on deleted comment:
If the goal is optimization, then the unreachable_unchecked tells the compiler there is no other option than to succeed and will remove the panic machinery.
Click here to open example
pub fn version_a(x: &mut [u8]) -> &mut GenericArray<u8, U24> {
if x.len() != U24::USIZE {
unsafe { std::hint::unreachable_unchecked() }
}
GenericArray::from_mut_slice(x)
}
pub fn version_b(x: &mut [u8]) -> &mut GenericArray<u8, U24> {
GenericArray::from_mut_slice(x)
}
compiles down to
playground::version_a:
movq %rdi, %rax
retq
playground::version_b:
subq $56, %rsp
movq %rsi, (%rsp)
cmpq $24, %rsi
jne .LBB4_1
movq %rdi, %rax
addq $56, %rsp
retq
.LBB4_1:
movq $0, 8(%rsp)
movq %rsp, %rdi
leaq 8(%rsp), %rsi
callq core::panicking::assert_failed
ud2
If the goal is to just be unsafe for the sake of being unsafe, that's just asking for trouble.
Thank you, this does (unergonomically, as you say) compile down to what I need. However, it also relies on:
-
GenericArray::from_mut_slicebeing inlined (its#[inline]attribute is only a hint, which the compiler can ignore); and -
an optimisation pass recognising that both tests (that in my fn and that in
GenericArray::from_mut_slice) can thus be omitted.
I'm quite happy with this workaround if exposing _unchecked methods is unacceptable to this library. Feel free to close. Thanks again!
As of 1.0, unsafe { GenericArray::try_from_mut_slice(slice).unwrap_unchecked() } should be sufficient. Still relies on the optimizations, but I've marked everything involved with that as #[inline(always)].