The TryFrom implementation to convert from a borrowed slice to a borrowed array requires that the length is exact:
impl<'a, T, const N: usize> TryFrom<&'a [T]> for &'a [T; N] {
type Error = TryFromSliceError;
fn try_from(slice: &[T]) -> Result<&[T; N], TryFromSliceError> {
if slice.len() == N {
let ptr = slice.as_ptr() as *const [T; N];
// SAFETY: ok because we just checked that the length fits
unsafe { Ok(&*ptr) }
} else {
Err(TryFromSliceError(()))
}
}
}
Why? Wouldn't it be fine to perform the conversion even if the length of the slice is greater than the length of the requested array? I would expect slice.len() >= N rather than == N.
I suppose the reasoning is, roughly, that From-implementations (or in this case TryFrom-implementations) ought to use their full argument, not ignore parts of it. Or put differently, at least some people will probably expect that &[T] converted to &[T; N] converts the whole thing, and in this case, the conversion as-is will catch more mistakes. There’s other possible ways to truncate an overlength slice; you can take the beginning, or the end, or something in the middle; the method name doesn’t specify so it’s best to do none of these.
Not saying that any of this is the reason, that’s just my own guesswork / intuition. By the way, this doesn’t stop you from achieving the behavior you’re after; just use
Froms that lose information are generally an anti-pattern, and thus Ok from TryFrom should also not lose information. For example, we could have u16: From<u32>, but that loses information so we don't.
It's much more convenient to index the slice inline (as @steffahn showed) than to add a check for the length.
zip is notorious for accidental logic errors when things turn out to not be the same length, and thus a few elements are accidentally silently ignored from one iterator or the other, resulting in things like Itertools::zip_eq. So Rust now generally will insist on things matching up, to help catch such things -- that's why copy_from_slice, for example, insists on it. (The docs there even mention using [..N] if you want to allow the mismatch -- which has the advantage that you can decide which of the slices you're allowing the mismatch on.)