From c8ea4b30e844fb226609c4e32dbbc59e555ac60f Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Thu, 16 May 2024 16:53:11 -0400 Subject: [PATCH] Rephrase conversion methods' documentation to accommodate DSTs (#1269) Makes progress on #29, #871. --- src/lib.rs | 339 +++++++++++++++++++++++++++-------------------------- src/ref.rs | 226 ++++++++++++++++++----------------- 2 files changed, 295 insertions(+), 270 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 446fecd932..db0deb7193 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1109,10 +1109,10 @@ pub unsafe trait TryFromBytes { /// copying. /// /// If the bytes of `candidate` are a valid instance of `Self`, this method - /// returns a reference to those bytes interpreted as a `Self`. If - /// `candidate.len() < size_of::()` or `candidate` is not aligned to - /// `align_of::()` or the bytes are not a valid instance of `Self`, - /// this returns `Err`. + /// returns a reference to those bytes interpreted as a `Self`. If the + /// length of `candidate` is not a valid size of `Self`, or if `candidate` + /// is not appropriately aligned, or if the bytes are not a valid instance + /// of `Self`, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -1202,12 +1202,12 @@ pub unsafe trait TryFromBytes { /// Attempts to interpret the prefix of the given `candidate` as a `&Self` /// without copying. /// - /// If the first `size_of::()` bytes of `candidate` are a valid - /// instance of `Self`, this method returns both a reference to those bytes - /// interpreted as a `Self`, and a reference to the remaining bytes. If - /// `candidate.len() < size_of::()` or `candidate` is not aligned to - /// `align_of::()` or the bytes are not a valid instance of `Self`, - /// this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the leading bytes of `candidate`. If that prefix is a valid instance of + /// `Self`, this method returns a reference to those bytes interpreted as + /// `Self`, and a reference to the remaining bytes. If there are + /// insufficient bytes, or if `candidate` is not appropriately aligned, or + /// if the bytes are not a valid instance of `Self`, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -1281,12 +1281,13 @@ pub unsafe trait TryFromBytes { /// Attempts to interpret the suffix of the given `candidate` as a `&Self` /// without copying. /// - /// If the last `size_of::()` bytes of `candidate` are a valid - /// instance of `Self`, this method returns both a reference to those bytes - /// interpreted as a `Self`, and a reference to the preceding bytes. If - /// `candidate.len() < size_of::()` or the suffix of `candidate` is - /// not aligned to `align_of::()` or the suffix of `candidate` is not - /// a valid instance of `Self`, this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the trailing bytes of `candidate`. If that suffix is a valid instance of + /// `Self`, this method returns a reference to those bytes interpreted as + /// `Self`, and a reference to the preceding bytes. If there are + /// insufficient bytes, or if the suffix of `candidate` would not be + /// appropriately aligned, or if the suffix is not a valid instance of + /// `Self`, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -1361,10 +1362,10 @@ pub unsafe trait TryFromBytes { /// copying. /// /// If the bytes of `candidate` are a valid instance of `Self`, this method - /// returns a reference to those bytes interpreted as a `Self`. If - /// `candidate.len() < size_of::()` or `candidate` is not aligned to - /// `align_of::()` or the bytes are not a valid instance of `Self`, - /// this returns `Err`. + /// returns a reference to those bytes interpreted as a `Self`. If the + /// length of `candidate` is not a valid size of `Self`, or if `candidate` + /// is not appropriately aligned, or if the bytes are not a valid instance + /// of `Self`, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -1455,12 +1456,12 @@ pub unsafe trait TryFromBytes { /// Attempts to interpret the prefix of the given `candidate` as a `&mut /// Self` without copying. /// - /// If the first `size_of::()` bytes of `candidate` are a valid - /// instance of `Self`, this method returns both a reference to those bytes - /// interpreted as a `Self`, and a reference to the remaining bytes. If - /// `candidate.len() < size_of::()` or `candidate` is not aligned to - /// `align_of::()` or the bytes are not a valid instance of `Self`, - /// this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the leading bytes of `candidate`. If that prefix is a valid instance of + /// `Self`, this method returns a reference to those bytes interpreted as + /// `Self`, and a reference to the remaining bytes. If there are + /// insufficient bytes, or if `candidate` is not appropriately aligned, or + /// if the bytes are not a valid instance of `Self`, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -1542,12 +1543,13 @@ pub unsafe trait TryFromBytes { /// Attempts to interpret the suffix of the given `candidate` as a `&mut /// Self` without copying. /// - /// If the last `size_of::()` bytes of `candidate` are a valid - /// instance of `Self`, this method returns both a reference to those bytes - /// interpreted as a `Self`, and a reference to the preceding bytes. If - /// `candidate.len() < size_of::()` or the suffix of `candidate` is - /// not aligned to `align_of::()` or the suffix of `candidate` is not - /// a valid instance of `Self`, this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the trailing bytes of `candidate`. If that suffix is a valid instance of + /// `Self`, this method returns a reference to those bytes interpreted as + /// `Self`, and a reference to the preceding bytes. If there are + /// insufficient bytes, or if the suffix of `candidate` would not be + /// appropriately aligned, or if the suffix is not a valid instance of + /// `Self`, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -1628,9 +1630,8 @@ pub unsafe trait TryFromBytes { /// Attempts to read the given `candidate` as a `Self`. /// - /// If the bytes of `candidate` are a valid instance of `Self`, reads those - /// bytes as `Self`. If `candidate.len() < size_of::()` or the bytes - /// are not a valid instance of `Self`, this returns `Err`. + /// If `candidate.len() != size_of::()` or the bytes are not a valid + /// instance of `Self`, this returns `Err`. /// /// # Examples /// @@ -2273,11 +2274,11 @@ pub unsafe trait FromBytes: FromZeros { where Self: Sized; - /// Interprets the given `bytes` as a `&Self` without copying. + /// Interprets the given bytes as a `&Self` without copying. /// - /// If `bytes.len()` does not correspond to a valid length for `Self`, or if - /// `bytes` is not aligned to `Self`'s alignment requirement, this returns - /// `Err`. + /// This method attempts to return a reference to `source` interpreted as a + /// `Self`. If the length of `source` is not a valid size of `Self`, or if + /// `source` is not appropriately aligned, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -2334,23 +2335,24 @@ pub unsafe trait FromBytes: FromZeros { /// ``` #[must_use = "has no side effects"] #[inline] - fn ref_from(bytes: &[u8]) -> Result<&Self, CastError<&[u8], Self>> + fn ref_from(source: &[u8]) -> Result<&Self, CastError<&[u8], Self>> where Self: KnownLayout + Immutable, { util::assert_dst_is_not_zst::(); - match Ptr::from_ref(bytes).try_cast_into_no_leftover::<_, BecauseImmutable>(None) { + match Ptr::from_ref(source).try_cast_into_no_leftover::<_, BecauseImmutable>(None) { Ok(ptr) => Ok(ptr.bikeshed_recall_valid().as_ref()), Err(err) => Err(err.map_src(|src| src.as_ref())), } } - /// Interprets the prefix of the given `bytes` as a `&Self` without copying. + /// Interprets the prefix of the given bytes as a `&Self` without copying. /// - /// This method returns both a reference to the first `size_of::()` - /// bytes of `bytes` interpreted as a `Self`, and a reference to the remaining - /// bytes. If `bytes.len() < size_of::()` or `bytes` is not aligned to - /// `align_of::()`, this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the leading bytes of `source`, then attempts to return both a reference + /// to those bytes interpreted as a `Self`, and a reference to the remaining + /// bytes. If there are insufficient bytes, or if `source` is not + /// appropriately aligned, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -2411,20 +2413,21 @@ pub unsafe trait FromBytes: FromZeros { /// ``` #[must_use = "has no side effects"] #[inline] - fn ref_from_prefix(bytes: &[u8]) -> Result<(&Self, &[u8]), CastError<&[u8], Self>> + fn ref_from_prefix(source: &[u8]) -> Result<(&Self, &[u8]), CastError<&[u8], Self>> where Self: KnownLayout + Immutable, { util::assert_dst_is_not_zst::(); - ref_from_prefix_suffix(bytes, None, CastType::Prefix) + ref_from_prefix_suffix(source, None, CastType::Prefix) } - /// Interprets the suffix of the given `bytes` as a `&Self` without copying. + /// Interprets the suffix of the given bytes as a `&Self` without copying. /// - /// This method returns both a reference to the last `size_of::()` - /// bytes of `bytes` interpreted as a `Self`, and a reference to the preceding - /// bytes. If `bytes.len() < size_of::()` or the suffix of `bytes` is - /// not aligned to `align_of::()`, this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the trailing bytes of `source`, then attempts to return both a reference + /// to those bytes interpreted as a `Self`, and a reference to the preceding + /// bytes. If there are insufficient bytes, or if that suffix of `source` is + /// not appropriately aligned, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -2471,18 +2474,19 @@ pub unsafe trait FromBytes: FromZeros { /// ``` #[must_use = "has no side effects"] #[inline] - fn ref_from_suffix(bytes: &[u8]) -> Result<(&[u8], &Self), CastError<&[u8], Self>> + fn ref_from_suffix(source: &[u8]) -> Result<(&[u8], &Self), CastError<&[u8], Self>> where Self: Immutable + KnownLayout, { util::assert_dst_is_not_zst::(); - ref_from_prefix_suffix(bytes, None, CastType::Suffix).map(swap) + ref_from_prefix_suffix(source, None, CastType::Suffix).map(swap) } - /// Interprets the given `bytes` as a `&mut Self` without copying. + /// Interprets the given bytes as a `&mut Self` without copying. /// - /// If `bytes.len() != size_of::()` or `bytes` is not aligned to - /// `align_of::()`, this returns `Err`. + /// This method attempts to return a reference to `source` interpreted as a + /// `Self`. If the length of `source` is not a valid size of `Self`, or if + /// `source` is not appropriately aligned, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -2539,24 +2543,25 @@ pub unsafe trait FromBytes: FromZeros { /// ``` #[must_use = "has no side effects"] #[inline] - fn mut_from(bytes: &mut [u8]) -> Result<&mut Self, CastError<&mut [u8], Self>> + fn mut_from(source: &mut [u8]) -> Result<&mut Self, CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout, { util::assert_dst_is_not_zst::(); - match Ptr::from_mut(bytes).try_cast_into_no_leftover::<_, BecauseExclusive>(None) { + match Ptr::from_mut(source).try_cast_into_no_leftover::<_, BecauseExclusive>(None) { Ok(ptr) => Ok(ptr.bikeshed_recall_valid().as_mut()), Err(err) => Err(err.map_src(|src| src.as_mut())), } } - /// Interprets the prefix of the given `bytes` as a `&mut Self` without + /// Interprets the prefix of the given bytes as a `&mut Self` without /// copying. /// - /// This method returns both a reference to the first `size_of::()` - /// bytes of `bytes` interpreted as a `Self`, and a reference to the remaining - /// bytes. If `bytes.len() < size_of::()` or `bytes` is not aligned to - /// `align_of::()`, this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the leading bytes of `source`, then attempts to return both a reference + /// to those bytes interpreted as a `Self`, and a reference to the remaining + /// bytes. If there are insufficient bytes, or if `source` is not + /// appropriately aligned, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -2616,22 +2621,23 @@ pub unsafe trait FromBytes: FromZeros { #[must_use = "has no side effects"] #[inline] fn mut_from_prefix( - bytes: &mut [u8], + source: &mut [u8], ) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout, { util::assert_dst_is_not_zst::(); - mut_from_prefix_suffix(bytes, None, CastType::Prefix) + mut_from_prefix_suffix(source, None, CastType::Prefix) } - /// Interprets the suffix of the given `bytes` as a `&mut Self` without + /// Interprets the suffix of the given bytes as a `&mut Self` without /// copying. /// - /// This method returns both a reference to the last `size_of::()` - /// bytes of `bytes` interpreted as a `Self`, and a reference to the preceding - /// bytes. If `bytes.len() < size_of::()` or the suffix of `bytes` is - /// not aligned to `align_of::()`, this returns `Err`. + /// This method computes the largest possible size of `Self` that can fit in + /// the trailing bytes of `source`, then attempts to return both a reference + /// to those bytes interpreted as a `Self`, and a reference to the preceding + /// bytes. If there are insufficient bytes, or if that suffix of `source` is + /// not appropriately aligned, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -2682,22 +2688,22 @@ pub unsafe trait FromBytes: FromZeros { #[must_use = "has no side effects"] #[inline] fn mut_from_suffix( - bytes: &mut [u8], + source: &mut [u8], ) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout, { util::assert_dst_is_not_zst::(); - mut_from_prefix_suffix(bytes, None, CastType::Suffix).map(swap) + mut_from_prefix_suffix(source, None, CastType::Suffix).map(swap) } - /// Interprets the given `bytes` as a `&Self` with a DST length equal to + /// Interprets the given bytes as a `&Self` with a DST length equal to /// `count`. /// - /// This method verifies that `bytes.len() == size_of::() * count` and - /// that `bytes` is aligned to `align_of::()`. It also ensures that - /// `sizeof::() * count` does not overflow a `usize`. If any of the - /// length, alignment, or overflow checks fail, it returns `Err`. + /// This method attempts to return a reference to `source` interpreted as a + /// `Self` with `count` trailing elements. If the length of `source` is not + /// equal to the size of `Self` with `count` elements, or if `source` is not + /// appropriately aligned, this returns `Err`. /// /// # Examples /// @@ -2749,27 +2755,25 @@ pub unsafe trait FromBytes: FromZeros { /// [`ref_from`]: FromBytes::ref_from #[must_use = "has no side effects"] #[inline] - fn ref_from_with_elems(bytes: &[u8], count: usize) -> Result<&Self, CastError<&[u8], Self>> + fn ref_from_with_elems(source: &[u8], count: usize) -> Result<&Self, CastError<&[u8], Self>> where Self: KnownLayout + Immutable, { - let bytes = Ptr::from_ref(bytes); - let maybe_slf = bytes.try_cast_into_no_leftover::<_, BecauseImmutable>(Some(count)); + let source = Ptr::from_ref(source); + let maybe_slf = source.try_cast_into_no_leftover::<_, BecauseImmutable>(Some(count)); match maybe_slf { Ok(slf) => Ok(slf.bikeshed_recall_valid().as_ref()), Err(err) => Err(err.map_src(|s| s.as_ref())), } } - /// Interprets the prefix of the given `bytes` as a `&[Self]` with length + /// Interprets the prefix of the given bytes as a DST `&Self` with length /// equal to `count` without copying. /// - /// This method verifies that `bytes.len() >= size_of::() * count` and - /// that `bytes` is aligned to `align_of::()`. It reinterprets the first - /// `size_of::() * count` bytes from `bytes` to construct a `&[Self]`, - /// and returns the remaining bytes to the caller. It also ensures that - /// `sizeof::() * count` does not overflow a `usize`. If any of the - /// length, alignment, or overflow checks fail, it returns `Err`. + /// This method attempts to return a reference to the prefix of `source` + /// interpreted as a `Self` with `count` trailing elements, and a reference + /// to the remaining bytes. If there are insufficient bytes, or if `source` + /// is not appropriately aligned, this returns `Err`. /// /// # Examples /// @@ -2824,35 +2828,33 @@ pub unsafe trait FromBytes: FromZeros { #[must_use = "has no side effects"] #[inline] fn ref_from_prefix_with_elems( - bytes: &[u8], + source: &[u8], count: usize, ) -> Result<(&Self, &[u8]), CastError<&[u8], Self>> where Self: KnownLayout + Immutable, { - ref_from_prefix_suffix(bytes, Some(count), CastType::Prefix) + ref_from_prefix_suffix(source, Some(count), CastType::Prefix) } #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::from_prefix_with_elems`")] #[doc(hidden)] #[must_use = "has no side effects"] #[inline] - fn slice_from_prefix(bytes: &[u8], count: usize) -> Option<(&[Self], &[u8])> + fn slice_from_prefix(source: &[u8], count: usize) -> Option<(&[Self], &[u8])> where Self: Sized + Immutable, { - <[Self]>::ref_from_prefix_with_elems(bytes, count).ok() + <[Self]>::ref_from_prefix_with_elems(source, count).ok() } - /// Interprets the suffix of the given `bytes` as a `&[Self]` with length + /// Interprets the suffix of the given bytes as a DST `&Self` with length /// equal to `count` without copying. /// - /// This method verifies that `bytes.len() >= size_of::() * count` and - /// that `bytes` is aligned to `align_of::()`. It reinterprets the last - /// `size_of::() * count` bytes from `bytes` to construct a `&[Self]`, - /// and returns the preceding bytes to the caller. It also ensures that - /// `sizeof::() * count` does not overflow a `usize`. If any of the - /// length, alignment, or overflow checks fail, it returns `Err`. + /// This method attempts to return a reference to the suffix of `source` + /// interpreted as a `Self` with `count` trailing elements, and a reference + /// to the preceding bytes. If there are insufficient bytes, or if that + /// suffix of `source` is not appropriately aligned, this returns `Err`. /// /// # Examples /// @@ -2907,44 +2909,44 @@ pub unsafe trait FromBytes: FromZeros { #[must_use = "has no side effects"] #[inline] fn ref_from_suffix_with_elems( - bytes: &[u8], + source: &[u8], count: usize, ) -> Result<(&[u8], &Self), CastError<&[u8], Self>> where Self: KnownLayout + Immutable, { - ref_from_prefix_suffix(bytes, Some(count), CastType::Suffix).map(swap) + ref_from_prefix_suffix(source, Some(count), CastType::Suffix).map(swap) } #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::from_prefix_with_elems`")] #[doc(hidden)] #[must_use = "has no side effects"] #[inline] - fn slice_from_suffix(bytes: &[u8], count: usize) -> Option<(&[u8], &[Self])> + fn slice_from_suffix(source: &[u8], count: usize) -> Option<(&[u8], &[Self])> where Self: Sized + Immutable, { - <[Self]>::ref_from_suffix_with_elems(bytes, count).ok() + <[Self]>::ref_from_suffix_with_elems(source, count).ok() } #[deprecated(since = "0.8.0", note = "`FromBytes::mut_from` now supports slices")] #[must_use = "has no side effects"] #[doc(hidden)] #[inline] - fn mut_slice_from(bytes: &mut [u8]) -> Option<&mut [Self]> + fn mut_slice_from(source: &mut [u8]) -> Option<&mut [Self]> where Self: Sized + IntoBytes, { - <[Self]>::mut_from(bytes).ok() + <[Self]>::mut_from(source).ok() } - /// Interprets the given `bytes` as a `&mut Self` with a DST length equal to + /// Interprets the given bytes as a `&mut Self` with a DST length equal to /// `count`. /// - /// This method verifies that `bytes.len() == size_of::() * count` and - /// that `bytes` is aligned to `align_of::()`. It also ensures that - /// `sizeof::() * count` does not overflow a `usize`. If any of the - /// length, alignment, or overflow checks fail, it returns `Err`. + /// This method attempts to return a reference to `source` interpreted as a + /// `Self` with `count` trailing elements. If the length of `source` is not + /// equal to the size of `Self` with `count` elements, or if `source` is not + /// appropriately aligned, this returns `Err`. /// /// # Examples /// @@ -3000,29 +3002,27 @@ pub unsafe trait FromBytes: FromZeros { #[must_use = "has no side effects"] #[inline] fn mut_from_with_elems( - bytes: &mut [u8], + source: &mut [u8], count: usize, ) -> Result<&mut Self, CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout + Immutable, { - let bytes = Ptr::from_mut(bytes); - let maybe_slf = bytes.try_cast_into_no_leftover::<_, BecauseImmutable>(Some(count)); + let source = Ptr::from_mut(source); + let maybe_slf = source.try_cast_into_no_leftover::<_, BecauseImmutable>(Some(count)); match maybe_slf { Ok(slf) => Ok(slf.bikeshed_recall_valid().as_mut()), Err(err) => Err(err.map_src(|s| s.as_mut())), } } - /// Interprets the prefix of the given `bytes` as a `&mut [Self]` with - /// length equal to `count` without copying. + /// Interprets the prefix of the given bytes as a `&mut [Self]` with length + /// equal to `count` without copying. /// - /// This method verifies that `bytes.len() >= size_of::() * count` and - /// that `bytes` is aligned to `align_of::()`. It reinterprets the first - /// `size_of::() * count` bytes from `bytes` to construct a `&[Self]`, - /// and returns the remaining bytes to the caller. It also ensures that - /// `sizeof::() * count` does not overflow a `usize`. If any of the - /// length, alignment, or overflow checks fail, it returns `Err`. + /// This method attempts to return a reference to the prefix of `source` + /// interpreted as a `Self` with `count` trailing elements, and a reference + /// to the preceding bytes. If there are insufficient bytes, or if `source` + /// is not appropriately aligned, this returns `Err`. /// /// # Examples /// @@ -3082,35 +3082,33 @@ pub unsafe trait FromBytes: FromZeros { #[must_use = "has no side effects"] #[inline] fn mut_from_prefix_with_elems( - bytes: &mut [u8], + source: &mut [u8], count: usize, ) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout, { - mut_from_prefix_suffix(bytes, Some(count), CastType::Prefix) + mut_from_prefix_suffix(source, Some(count), CastType::Prefix) } #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::mut_from_prefix_with_elems`")] #[doc(hidden)] #[must_use = "has no side effects"] #[inline] - fn mut_slice_from_prefix(bytes: &mut [u8], count: usize) -> Option<(&mut [Self], &mut [u8])> + fn mut_slice_from_prefix(source: &mut [u8], count: usize) -> Option<(&mut [Self], &mut [u8])> where Self: Sized + IntoBytes, { - <[Self]>::mut_from_prefix_with_elems(bytes, count).ok() + <[Self]>::mut_from_prefix_with_elems(source, count).ok() } - /// Interprets the suffix of the given `bytes` as a `&mut [Self]` with length + /// Interprets the suffix of the given bytes as a `&mut [Self]` with length /// equal to `count` without copying. /// - /// This method verifies that `bytes.len() >= size_of::() * count` and - /// that `bytes` is aligned to `align_of::()`. It reinterprets the last - /// `size_of::() * count` bytes from `bytes` to construct a `&[Self]`, - /// and returns the preceding bytes to the caller. It also ensures that - /// `sizeof::() * count` does not overflow a `usize`. If any of the - /// length, alignment, or overflow checks fail, it returns `Err`. + /// This method attempts to return a reference to the suffix of `source` + /// interpreted as a `Self` with `count` trailing elements, and a reference + /// to the remaining bytes. If there are insufficient bytes, or if that + /// suffix of `source` is not appropriately aligned, this returns `Err`. /// /// # Examples /// @@ -3170,28 +3168,28 @@ pub unsafe trait FromBytes: FromZeros { #[must_use = "has no side effects"] #[inline] fn mut_from_suffix_with_elems( - bytes: &mut [u8], + source: &mut [u8], count: usize, ) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>> where Self: IntoBytes + KnownLayout, { - mut_from_prefix_suffix(bytes, Some(count), CastType::Suffix).map(swap) + mut_from_prefix_suffix(source, Some(count), CastType::Suffix).map(swap) } #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::mut_from_suffix_with_elems`")] #[doc(hidden)] #[inline] - fn mut_slice_from_suffix(bytes: &mut [u8], count: usize) -> Option<(&mut [u8], &mut [Self])> + fn mut_slice_from_suffix(source: &mut [u8], count: usize) -> Option<(&mut [u8], &mut [Self])> where Self: Sized + IntoBytes, { - <[Self]>::mut_from_suffix_with_elems(bytes, count).ok() + <[Self]>::mut_from_suffix_with_elems(source, count).ok() } - /// Reads a copy of `Self` from `bytes`. + /// Reads a copy of `Self` from the given bytes. /// - /// If `bytes.len() != size_of::()`, `read_from` returns `Err`. + /// If `source.len() != size_of::()`, `read_from` returns `Err`. /// /// # Examples /// @@ -3220,11 +3218,11 @@ pub unsafe trait FromBytes: FromZeros { /// ``` #[must_use = "has no side effects"] #[inline] - fn read_from(bytes: &[u8]) -> Result> + fn read_from(source: &[u8]) -> Result> where Self: Sized, { - match Ref::<_, Unalign>::sized_from(bytes) { + match Ref::<_, Unalign>::sized_from(source) { Ok(r) => Ok(r.read().into_inner()), Err(CastError::Size(e)) => Err(e.with_dst()), Err(CastError::Alignment(_)) => unreachable!(), @@ -3232,11 +3230,11 @@ pub unsafe trait FromBytes: FromZeros { } } - /// Reads a copy of `Self` from the prefix of `bytes`. + /// Reads a copy of `Self` from the prefix of the given bytes. /// - /// `read_from_prefix` reads a `Self` from the first `size_of::()` - /// bytes of `bytes`, returning that `Self` and any remaining bytes. If - /// `bytes.len() < size_of::()`, it returns `Err`. + /// This attempts to read a `Self` from the first `size_of::()` bytes + /// of `source`, returning that `Self` and any remaining bytes. If + /// `source.len() < size_of::()`, it returns `Err`. /// /// # Examples /// @@ -3266,11 +3264,11 @@ pub unsafe trait FromBytes: FromZeros { /// ``` #[must_use = "has no side effects"] #[inline] - fn read_from_prefix(bytes: &[u8]) -> Result<(Self, &[u8]), SizeError<&[u8], Self>> + fn read_from_prefix(source: &[u8]) -> Result<(Self, &[u8]), SizeError<&[u8], Self>> where Self: Sized, { - match Ref::<_, Unalign>::sized_from_prefix(bytes) { + match Ref::<_, Unalign>::sized_from_prefix(source) { Ok((r, suffix)) => Ok((r.read().into_inner(), suffix)), Err(CastError::Size(e)) => Err(e.with_dst()), Err(CastError::Alignment(_)) => unreachable!(), @@ -3278,11 +3276,11 @@ pub unsafe trait FromBytes: FromZeros { } } - /// Reads a copy of `Self` from the suffix of `bytes`. + /// Reads a copy of `Self` from the suffix of the given bytes. /// - /// `read_from_suffix` reads a `Self` from the last `size_of::()` - /// bytes of `bytes`, returning that `Self` and any preceding bytes. If - /// `bytes.len() < size_of::()`, it returns `Err`. + /// This attempts to read a `Self` from the last `size_of::()` bytes + /// of `source`, returning that `Self` and any preceding bytes. If + /// `source.len() < size_of::()`, it returns `Err`. /// /// # Examples /// @@ -3306,11 +3304,11 @@ pub unsafe trait FromBytes: FromZeros { /// ``` #[must_use = "has no side effects"] #[inline] - fn read_from_suffix(bytes: &[u8]) -> Result<(&[u8], Self), CastError<&[u8], Self>> + fn read_from_suffix(source: &[u8]) -> Result<(&[u8], Self), CastError<&[u8], Self>> where Self: Sized, { - match Ref::<_, Unalign>::sized_from_suffix(bytes) { + match Ref::<_, Unalign>::sized_from_suffix(source) { Ok((prefix, r)) => Ok((prefix, r.read().into_inner())), Err(CastError::Size(e)) => Err(CastError::Size(e.with_dst())), Err(CastError::Alignment(_)) => unreachable!(), @@ -3322,33 +3320,48 @@ pub unsafe trait FromBytes: FromZeros { #[allow(clippy::must_use_candidate)] #[doc(hidden)] #[inline] - fn slice_from(bytes: &[u8]) -> Option<&[Self]> + fn slice_from(source: &[u8]) -> Option<&[Self]> where Self: Sized + Immutable, { - <[Self]>::ref_from(bytes).ok() + <[Self]>::ref_from(source).ok() } } +/// Interprets the given affix of the given bytes as a `&Self` without copying. +/// +/// This method computes the largest possible size of `Self` that can fit in the +/// prefix or suffix bytes of `source`, then attempts to return both a reference +/// to those bytes interpreted as a `Self`, and a reference to the excess bytes. +/// If there are insufficient bytes, or if that affix of `source` is not +/// appropriately aligned, this returns `Err`. #[inline(always)] fn ref_from_prefix_suffix( - bytes: &[u8], + source: &[u8], meta: Option, cast_type: CastType, ) -> Result<(&T, &[u8]), CastError<&[u8], T>> { - let (slf, prefix_suffix) = Ptr::from_ref(bytes) + let (slf, prefix_suffix) = Ptr::from_ref(source) .try_cast_into::<_, BecauseImmutable>(cast_type, meta) .map_err(|err| err.map_src(|s| s.as_ref()))?; Ok((slf.bikeshed_recall_valid().as_ref(), prefix_suffix.as_ref())) } +/// Interprets the given affix of the given bytes as a `&mut Self` without +/// copying. +/// +/// This method computes the largest possible size of `Self` that can fit in the +/// prefix or suffix bytes of `source`, then attempts to return both a reference +/// to those bytes interpreted as a `Self`, and a reference to the excess bytes. +/// If there are insufficient bytes, or if that affix of `source` is not +/// appropriately aligned, this returns `Err`. #[inline(always)] fn mut_from_prefix_suffix( - bytes: &mut [u8], + source: &mut [u8], meta: Option, cast_type: CastType, ) -> Result<(&mut T, &mut [u8]), CastError<&mut [u8], T>> { - let (slf, prefix_suffix) = Ptr::from_mut(bytes) + let (slf, prefix_suffix) = Ptr::from_mut(source) .try_cast_into::<_, BecauseExclusive>(cast_type, meta) .map_err(|err| err.map_src(|s| s.as_mut()))?; Ok((slf.bikeshed_recall_valid().as_mut(), prefix_suffix.as_mut())) @@ -6086,10 +6099,10 @@ mod proofs { match field.size_info { SizeInfo::Sized { size: field_size } => { if let SizeInfo::Sized { size: composite_size } = composite.size_info { - // If the trailing field is sized, the resulting layout - // will be sized. Its size will be the sum of the - // preceeding layout, the size of the new field, and the - // size of inter-field padding between the two. + // If the trailing field is sized, the resulting layout will + // be sized. Its size will be the sum of the preceding + // layout, the size of the new field, and the size of + // inter-field padding between the two. assert_eq!(composite_size, offset + field_size); let field_analog = diff --git a/src/ref.rs b/src/ref.rs index accf831b7d..aeef5cdbc0 100644 --- a/src/ref.rs +++ b/src/ref.rs @@ -273,11 +273,10 @@ where B: ByteSlice, T: KnownLayout + Immutable + ?Sized, { - /// Constructs a new `Ref` from a byte slice. + /// Constructs a `Ref` from a byte slice. /// - /// `from_bytes` verifies that `bytes.len() == size_of::()` and that - /// `bytes` is aligned to `align_of::()`, and constructs a new `Ref`. If - /// either of these checks fail, it returns `None`. + /// If the length of `source` is not a valid size of `T`, or if `source` is + /// not appropriately aligned for `T`, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -300,15 +299,15 @@ where /// ``` #[must_use = "has no side effects"] #[inline] - pub fn from_bytes(bytes: B) -> Result, CastError> { + pub fn from_bytes(source: B) -> Result, CastError> { util::assert_dst_is_not_zst::(); if let Err(e) = - Ptr::from_ref(bytes.deref()).try_cast_into_no_leftover::(None) + Ptr::from_ref(source.deref()).try_cast_into_no_leftover::(None) { - return Err(e.with_src(()).with_src(bytes)); + return Err(e.with_src(()).with_src(source)); } // SAFETY: `try_cast_into_no_leftover` validates size and alignment. - Ok(unsafe { Ref::new_unchecked(bytes) }) + Ok(unsafe { Ref::new_unchecked(source) }) } } @@ -317,13 +316,13 @@ where B: SplitByteSlice, T: KnownLayout + Immutable + ?Sized, { - /// Constructs a new `Ref` from the prefix of a byte slice. + /// Constructs a `Ref` from the prefix of a byte slice. /// - /// `from_prefix` verifies that `bytes.len() >= size_of::()` and that - /// `bytes` is aligned to `align_of::()`. It consumes the first - /// `size_of::()` bytes from `bytes` to construct a `Ref`, and returns - /// the remaining bytes to the caller. If either the length or alignment - /// checks fail, it returns `None`. + /// This method computes the largest possible size of `T` that can fit in + /// the leading bytes of `source`, then attempts to return both a `Ref` to + /// those bytes, and a reference to the remaining bytes. If there are + /// insufficient bytes, or if `source` is not appropriately aligned, this + /// returns `Err`. /// /// # Compile-Time Assertions /// @@ -346,42 +345,42 @@ where /// ``` #[must_use = "has no side effects"] #[inline] - pub fn from_prefix(bytes: B) -> Result<(Ref, B), CastError> { + pub fn from_prefix(source: B) -> Result<(Ref, B), CastError> { util::assert_dst_is_not_zst::(); - let remainder = match Ptr::from_ref(bytes.deref()) + let remainder = match Ptr::from_ref(source.deref()) .try_cast_into::(CastType::Prefix, None) { Ok((_, remainder)) => remainder, Err(e) => { - return Err(e.with_src(()).with_src(bytes)); + return Err(e.with_src(()).with_src(source)); } }; - // SAFETY: `remainder` is constructed as a subset of `bytes`, and so it - // cannot have a larger size than `bytes`. Both of their `len` methods - // measure bytes (`bytes` deref's to `[u8]`, and `remainder` is a - // `Ptr<[u8]>`), so `bytes.len() >= remainder.len()`. Thus, this cannot + // SAFETY: `remainder` is constructed as a subset of `source`, and so it + // cannot have a larger size than `source`. Both of their `len` methods + // measure bytes (`source` deref's to `[u8]`, and `remainder` is a + // `Ptr<[u8]>`), so `source.len() >= remainder.len()`. Thus, this cannot // underflow. #[allow(unstable_name_collisions, clippy::incompatible_msrv)] - let split_at = unsafe { bytes.len().unchecked_sub(remainder.len()) }; + let split_at = unsafe { source.len().unchecked_sub(remainder.len()) }; let (bytes, suffix) = - try_split_at(bytes, split_at).map_err(|b| SizeError::new(b).into())?; + try_split_at(source, split_at).map_err(|b| SizeError::new(b).into())?; // SAFETY: `try_cast_into` validates size and alignment, and returns a - // `split_at` that indicates how many bytes of `bytes` correspond to a + // `split_at` that indicates how many bytes of `source` correspond to a // valid `T`. By safety postcondition on `SplitByteSlice::try_split_at` - // we can rely on `try_split_at` to produce the correct `bytes` and + // we can rely on `try_split_at` to produce the correct `source` and // `suffix`. let r = unsafe { Ref::new_unchecked(bytes) }; Ok((r, suffix)) } - /// Constructs a new `Ref` from the suffix of a byte slice. + /// Constructs a `Ref` from the suffix of a byte slice. /// - /// `from_suffix` verifies that `bytes.len() >= size_of::()` and that the - /// last `size_of::()` bytes of `bytes` are aligned to `align_of::()`. - /// It consumes the last `size_of::()` bytes from `bytes` to construct a - /// `Ref`, and returns the preceding bytes to the caller. If either the - /// length or alignment checks fail, it returns `None`. + /// This method computes the largest possible size of `T` that can fit in + /// the trailing bytes of `source`, then attempts to return both a `Ref` to + /// those bytes, and a reference to the preceding bytes. If there are + /// insufficient bytes, or if that suffix of `source` is not appropriately + /// aligned, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -404,23 +403,23 @@ where /// ``` #[must_use = "has no side effects"] #[inline] - pub fn from_suffix(bytes: B) -> Result<(B, Ref), CastError> { + pub fn from_suffix(source: B) -> Result<(B, Ref), CastError> { util::assert_dst_is_not_zst::(); - let remainder = match Ptr::from_ref(bytes.deref()) + let remainder = match Ptr::from_ref(source.deref()) .try_cast_into::(CastType::Suffix, None) { Ok((_, remainder)) => remainder, Err(e) => { let e = e.with_src(()); - return Err(e.with_src(bytes)); + return Err(e.with_src(source)); } }; let split_at = remainder.len(); let (prefix, bytes) = - try_split_at(bytes, split_at).map_err(|b| SizeError::new(b).into())?; + try_split_at(source, split_at).map_err(|b| SizeError::new(b).into())?; // SAFETY: `try_cast_into` validates size and alignment, and returns a - // `try_split_at` that indicates how many bytes of `bytes` correspond to + // `try_split_at` that indicates how many bytes of `source` correspond to // a valid `T`. By safety postcondition on // `SplitByteSlice::try_split_at` we can rely on `try_split_at` to // produce the correct `prefix` and `bytes`. @@ -434,20 +433,25 @@ where B: ByteSlice, T: KnownLayout + Immutable + ?Sized, { - // TODO(#29), TODO(#871): Pick a name and make this public. Make sure to - // update references to this name in `#[deprecated]` attributes elsewhere. - #[doc(hidden)] + /// Constructs a `Ref` from the given bytes with DST length equal to `count` + /// without copying. + /// + /// This method attempts to return a `Ref` to the prefix of `source` + /// interpreted as a `T` with `count` trailing elements, and a reference to + /// the remaining bytes. If the length of `source` is not equal to the size + /// of `Self` with `count` elements, or if `source` is not appropriately + /// aligned, this returns `Err`. #[inline] - pub fn from_bytes_with_elems(bytes: B, count: usize) -> Result, CastError> { + pub fn from_bytes_with_elems(source: B, count: usize) -> Result, CastError> { util::assert_dst_is_not_zst::(); let expected_len = match count.size_for_metadata(T::LAYOUT) { Some(len) => len, - None => return Err(SizeError::new(bytes).into()), + None => return Err(SizeError::new(source).into()), }; - if bytes.len() != expected_len { - return Err(SizeError::new(bytes).into()); + if source.len() != expected_len { + return Err(SizeError::new(source).into()); } - Self::from_bytes(bytes) + Self::from_bytes(source) } } @@ -456,51 +460,53 @@ where B: SplitByteSlice, T: KnownLayout + Immutable + ?Sized, { - // TODO(#29), TODO(#871): Pick a name and make this public. Make sure to - // update references to this name in `#[deprecated]` attributes elsewhere. - #[doc(hidden)] + /// Constructs a `Ref` from the prefix of the given bytes with DST + /// length equal to `count` without copying. + /// + /// This method attempts to return a `Ref` to the prefix of `source` + /// interpreted as a `T` with `count` trailing elements, and a reference to + /// the remaining bytes. If there are insufficient bytes, or if `source` is + /// not appropriately aligned, this returns `Err`. #[inline] pub fn from_prefix_with_elems( - bytes: B, + source: B, count: usize, ) -> Result<(Ref, B), CastError> { util::assert_dst_is_not_zst::(); let expected_len = match count.size_for_metadata(T::LAYOUT) { Some(len) => len, - None => return Err(SizeError::new(bytes).into()), + None => return Err(SizeError::new(source).into()), }; - if bytes.len() < expected_len { - return Err(SizeError::new(bytes).into()); + if source.len() < expected_len { + return Err(SizeError::new(source).into()); } - let (prefix, bytes) = bytes.split_at(expected_len); + let (prefix, bytes) = source.split_at(expected_len); Self::from_bytes(prefix).map(move |l| (l, bytes)) } -} -impl Ref -where - B: SplitByteSlice, - T: KnownLayout + Immutable + ?Sized, -{ - // TODO(#29), TODO(#871): Pick a name and make this public. Make sure to - // update references to this name in `#[deprecated]` attributes elsewhere. - #[doc(hidden)] + /// Constructs a `Ref` from the suffix of the given bytes with DST length + /// equal to `count` without copying. + /// + /// This method attempts to return a `Ref` to the suffix of `source` + /// interpreted as a `T` with `count` trailing elements, and a reference to + /// the preceding bytes. If there are insufficient bytes, or if that suffix + /// of `source` is not appropriately aligned, this returns `Err`. #[inline] pub fn from_suffix_with_elems( - bytes: B, + source: B, count: usize, ) -> Result<(B, Ref), CastError> { util::assert_dst_is_not_zst::(); let expected_len = match count.size_for_metadata(T::LAYOUT) { Some(len) => len, - None => return Err(SizeError::new(bytes).into()), + None => return Err(SizeError::new(source).into()), }; - let split_at = if let Some(split_at) = bytes.len().checked_sub(expected_len) { + let split_at = if let Some(split_at) = source.len().checked_sub(expected_len) { split_at } else { - return Err(SizeError::new(bytes).into()); + return Err(SizeError::new(source).into()); }; - let (bytes, suffix) = bytes.split_at(split_at); + let (bytes, suffix) = source.split_at(split_at); Self::from_bytes(suffix).map(move |l| (bytes, l)) } } @@ -510,11 +516,11 @@ where B: ByteSlice, T: Unaligned + KnownLayout + Immutable + ?Sized, { - /// Constructs a new `Ref` for a type with no alignment requirement from a - /// byte slice. + /// Constructs a `Ref` for a type with no alignment requirement from a byte + /// slice. /// - /// `unaligned_from` verifies that `bytes.len() == size_of::()` and - /// constructs a new `Ref`. If the check fails, it returns `None`. + /// If the length of `source` is not a valid size of `T`, this returns + /// `Err`. /// /// # Compile-Time Assertions /// @@ -537,9 +543,9 @@ where /// ``` #[must_use = "has no side effects"] #[inline(always)] - pub fn unaligned_from(bytes: B) -> Result, SizeError> { + pub fn unaligned_from(source: B) -> Result, SizeError> { util::assert_dst_is_not_zst::(); - match Ref::from_bytes(bytes) { + match Ref::from_bytes(source) { Ok(dst) => Ok(dst), Err(CastError::Size(e)) => Err(e), Err(CastError::Alignment(_)) => unreachable!(), @@ -553,13 +559,13 @@ where B: SplitByteSlice, T: Unaligned + KnownLayout + Immutable + ?Sized, { - /// Constructs a new `Ref` for a type with no alignment requirement from the + /// Constructs a `Ref` for a type with no alignment requirement from the /// prefix of a byte slice. /// - /// `unaligned_from_prefix` verifies that `bytes.len() >= size_of::()`. - /// It consumes the first `size_of::()` bytes from `bytes` to construct a - /// `Ref`, and returns the remaining bytes to the caller. If the length - /// check fails, it returns `None`. + /// This method computes the largest possible size of `T` that can fit in + /// the leading bytes of `source`, then attempts to return both a `Ref` to + /// those bytes, and a reference to the remaining bytes. If there are + /// insufficient bytes, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -582,22 +588,22 @@ where /// ``` #[must_use = "has no side effects"] #[inline(always)] - pub fn unaligned_from_prefix(bytes: B) -> Result<(Ref, B), SizeError> { + pub fn unaligned_from_prefix(source: B) -> Result<(Ref, B), SizeError> { util::assert_dst_is_not_zst::(); - Ref::from_prefix(bytes).map_err(|e| match e { + Ref::from_prefix(source).map_err(|e| match e { CastError::Size(e) => e, CastError::Alignment(_) => unreachable!(), CastError::Validity(i) => match i {}, }) } - /// Constructs a new `Ref` for a type with no alignment requirement from the + /// Constructs a `Ref` for a type with no alignment requirement from the /// suffix of a byte slice. /// - /// `unaligned_from_suffix` verifies that `bytes.len() >= size_of::()`. - /// It consumes the last `size_of::()` bytes from `bytes` to construct a - /// `Ref`, and returns the preceding bytes to the caller. If the length - /// check fails, it returns `None`. + /// This method computes the largest possible size of `T` that can fit in + /// the trailing bytes of `source`, then attempts to return both a `Ref` to + /// those bytes, and a reference to the preceding bytes. If there are + /// insufficient bytes, this returns `Err`. /// /// # Compile-Time Assertions /// @@ -620,9 +626,9 @@ where /// ``` #[must_use = "has no side effects"] #[inline(always)] - pub fn unaligned_from_suffix(bytes: B) -> Result<(B, Ref), SizeError> { + pub fn unaligned_from_suffix(source: B) -> Result<(B, Ref), SizeError> { util::assert_dst_is_not_zst::(); - Ref::from_suffix(bytes).map_err(|e| match e { + Ref::from_suffix(source).map_err(|e| match e { CastError::Size(e) => e, CastError::Alignment(_) => unreachable!(), CastError::Validity(i) => match i {}, @@ -635,16 +641,20 @@ where B: ByteSlice, T: KnownLayout + Unaligned + Immutable + ?Sized, { - // TODO(#29), TODO(#871): Pick a name and make this public. Make sure to - // update references to this name in `#[deprecated]` attributes elsewhere. - #[doc(hidden)] + /// Constructs a `Ref` from the given bytes with DST length equal to `count` + /// without copying. + /// + /// This method attempts to return a `Ref` to the prefix of `source` + /// interpreted as a `T` with `count` trailing elements, and a reference to + /// the remaining bytes. If the length of `source` is not equal to the size + /// of `Self` with `count` elements, this returns `Err`. #[inline] pub fn unaligned_from_bytes_with_elems( - bytes: B, + source: B, count: usize, ) -> Result, SizeError> { util::assert_dst_is_not_zst::(); - Self::from_bytes_with_elems(bytes, count).map_err(|e| match e { + Self::from_bytes_with_elems(source, count).map_err(|e| match e { CastError::Size(e) => e, CastError::Alignment(_) => unreachable!(), CastError::Validity(i) => match i {}, @@ -657,38 +667,40 @@ where B: SplitByteSlice, T: KnownLayout + Unaligned + Immutable + ?Sized, { - // TODO(#29), TODO(#871): Pick a name and make this public. Make sure to - // update references to this name in `#[deprecated]` attributes elsewhere. - #[doc(hidden)] + /// Constructs a `Ref` from the prefix of the given bytes with DST + /// length equal to `count` without copying. + /// + /// This method attempts to return a `Ref` to the prefix of `source` + /// interpreted as a `T` with `count` trailing elements, and a reference to + /// the remaining bytes. If there are insufficient bytes, this returns + /// `Err`. #[inline] pub fn unaligned_from_prefix_with_elems( - bytes: B, + source: B, count: usize, ) -> Result<(Ref, B), SizeError> { util::assert_dst_is_not_zst::(); - Self::from_prefix_with_elems(bytes, count).map_err(|e| match e { + Self::from_prefix_with_elems(source, count).map_err(|e| match e { CastError::Size(e) => e, CastError::Alignment(_) => unreachable!(), CastError::Validity(i) => match i {}, }) } -} -impl Ref -where - B: SplitByteSlice, - T: KnownLayout + Unaligned + Immutable + ?Sized, -{ - // TODO(#29), TODO(#871): Pick a name and make this public. Make sure to - // update references to this name in `#[deprecated]` attributes elsewhere. - #[doc(hidden)] + /// Constructs a `Ref` from the suffix of the given bytes with DST length + /// equal to `count` without copying. + /// + /// This method attempts to return a `Ref` to the suffix of `source` + /// interpreted as a `T` with `count` trailing elements, and a reference to + /// the preceding bytes. If there are insufficient bytes, this returns + /// `Err`. #[inline] pub fn unaligned_from_suffix_with_elems( - bytes: B, + source: B, count: usize, ) -> Result<(B, Ref), SizeError> { util::assert_dst_is_not_zst::(); - Self::from_suffix_with_elems(bytes, count).map_err(|e| match e { + Self::from_suffix_with_elems(source, count).map_err(|e| match e { CastError::Size(e) => e, CastError::Alignment(_) => unreachable!(), CastError::Validity(i) => match i {},