is there a way in std to convert a slice to an array reference without the length check? If not, what would be the proper way? Would the following code be correct/idiomatic?
// SAFETY: length of slice must be equal to N
unsafe fn slice_to_array_unchecked<T, const N: usize>(slice: &[T]) -> &[T; N] {
debug_assert!(slice.len() == N);
&*(slice as *const _ as *const _)
}
fn main() {
let v: Vec<i32> = vec![10, 20, 30];
let array_ref: &[i32; 3] = unsafe { slice_to_array_unchecked(&v) };
assert_eq!(array_ref, &[10, 20, 30]);
}
I’m sorry, this is not necessarily directed at you but also at other potential readers… but in general, it’s important to note that bound checks are usually not all that expensive, so only use unsafe for this if it’s actually benefiting performance, and if the use-cases are well reviewed.
So in most cases, the actually “idiomatic” approach would be to use safe rust and stick to .try_into().unwrap().
Yes, I normally refrain from using unsafe for that. My application case is a memory-mapped database (mmtkvdb), where corrupted on-disk data can lead to UB anyway (see also: Avoiding unsafe when using a C library: LMDB). So the whole thing is inherently unsafe anyway, and the idea is to have a very fast access to the underlying data. Consequently, all implementations of mmtkvdb::Storable are unsafe impls.