diff --git a/hybrid-array/src/lib.rs b/hybrid-array/src/lib.rs index 94733dad..a912e925 100644 --- a/hybrid-array/src/lib.rs +++ b/hybrid-array/src/lib.rs @@ -102,7 +102,10 @@ where // TODO(tarcieri): deprecate this before the v0.2 release // #[deprecated(since = "0.2.0", note = "use TryFrom instead")] #[inline] - pub fn ref_from_slice(slice: &[T]) -> &Self { + pub fn ref_from_slice<'a>(slice: &'a [T]) -> &'a Self + where + &'a Self: TryFrom<&'a [T], Error = TryFromSliceError>, + { slice.try_into().expect("slice length mismatch") } @@ -114,7 +117,10 @@ where // TODO(tarcieri): deprecate this before the v0.2 release // #[deprecated(since = "0.2.0", note = "use TryFrom instead")] #[inline] - pub fn ref_from_mut_slice(slice: &mut [T]) -> &mut Self { + pub fn ref_from_mut_slice<'a>(slice: &'a mut [T]) -> &'a mut Self + where + &'a mut Self: TryFrom<&'a mut [T], Error = TryFromSliceError>, + { slice.try_into().expect("slice length mismatch") } @@ -128,9 +134,9 @@ where #[inline] pub fn clone_from_slice(slice: &[T]) -> Self where - Self: Clone, + T: Clone, { - slice.try_into().expect("slice length mismatch") + Self::from_fn(|n| slice[n].clone()) } /// Concatenates `self` with `other`. @@ -482,10 +488,10 @@ where } } -impl<'a, T, U> TryFrom<&'a [T]> for Array +impl<'a, T, U, const N: usize> TryFrom<&'a [T]> for Array where - Self: Clone, - U: ArraySize, + Self: ArrayOps + Clone, + U: ArraySize = [T; N]>, { type Error = TryFromSliceError; @@ -495,35 +501,37 @@ where } } -impl<'a, T, U> TryFrom<&'a [T]> for &'a Array +impl<'a, T, U, const N: usize> TryFrom<&'a [T]> for &'a Array where - U: ArraySize, + Array: ArrayOps, + U: ArraySize = [T; N]>, { type Error = TryFromSliceError; #[inline] fn try_from(slice: &'a [T]) -> Result { - check_slice_length::(slice)?; + let array_ref = <&'a [T; N]>::try_from(slice)?; // SAFETY: `Array` is a `repr(transparent)` newtype for a core // array with length checked above. - Ok(unsafe { &*(slice.as_ptr() as *const Array) }) + Ok(unsafe { &*(array_ref.as_ptr() as *const Array) }) } } -impl<'a, T, U> TryFrom<&'a mut [T]> for &'a mut Array +impl<'a, T, U, const N: usize> TryFrom<&'a mut [T]> for &'a mut Array where - U: ArraySize, + Array: ArrayOps, + U: ArraySize = [T; N]>, { type Error = TryFromSliceError; #[inline] fn try_from(slice: &'a mut [T]) -> Result { - check_slice_length::(slice)?; + let array_ref = <&'a mut [T; N]>::try_from(slice)?; // SAFETY: `Array` is a `repr(transparent)` newtype for a core // array with length checked above. - Ok(unsafe { &mut *(slice.as_ptr() as *mut Array) }) + Ok(unsafe { &mut *(array_ref.as_ptr() as *mut Array) }) } } @@ -546,22 +554,6 @@ where { } -/// Generate a [`TryFromSliceError`] if the slice doesn't match the given length. -#[cfg_attr(debug_assertions, allow(clippy::panic_in_result_fn))] -fn check_slice_length(slice: &[T]) -> Result<(), TryFromSliceError> { - debug_assert_eq!(Array::<(), U>::default().len(), U::USIZE); - - if slice.len() != U::USIZE { - // Hack: `TryFromSliceError` lacks a public constructor - <&[T; 1]>::try_from([].as_slice())?; - - #[cfg(debug_assertions)] - unreachable!(); - } - - Ok(()) -} - /// Array operations which are const generic over a given array size. pub trait ArrayOps: Borrow<[T; N]>