diff --git a/src/error.rs b/src/error.rs index 317b5845f7..501d37c410 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,7 +11,8 @@ //! //! ## Single failure mode errors //! -//! Generally speaking, zerocopy's conversions may fail for one of up to three reasons: +//! Generally speaking, zerocopy's conversions may fail for one of up to three +//! reasons: //! - [`AlignmentError`]: the conversion source was improperly aligned //! - [`SizeError`]: the conversion source was of incorrect size //! - [`ValidityError`]: the conversion source contained invalid data @@ -28,6 +29,15 @@ //! - [`TryCastError`]: the error type of fallible reference conversions //! - [`TryReadError`]: the error type of fallible read conversions //! +//! ## [`Unaligned`] destination types +//! +//! For [`Unaligned`] destination types, alignment errors are impossible. All +//! compound error types support infallibly discarding the alignment error via +//! [`From`] so long as `Dst: Unaligned`. For example, see [`>::from`][size-error-from]. +//! +//! [size-error-from]: struct.SizeError.html#method.from-1 +//! //! ## Accessing the conversion source //! //! All error types provide an `into_src` method that converts the error into @@ -63,8 +73,8 @@ //! ## `Send`, `Sync`, and `'static` //! //! Our error types are `Send`, `Sync`, and `'static` when their `Src` parameter -//! is `Send`, `Sync`, or `'static`, respectively. This can cause issues when -//! an error is sent or synchronized across threads; e.g.: +//! is `Send`, `Sync`, or `'static`, respectively. This can cause issues when an +//! error is sent or synchronized across threads; e.g.: //! //! ```compile_fail,E0515 //! use zerocopy::*; @@ -164,7 +174,7 @@ impl From Result<&Bools, UnalignedTryCastError<&[u8], Bools>> { + /// fn parse(bytes: &[u8]) -> Result<&Bools, AlignedTryCastError<&[u8], Bools>> { /// // Since `Bools: Unaligned`, we can infallibly discard /// // the alignment error. /// Bools::try_ref_from_bytes(bytes).map_err(Into::into) @@ -881,10 +891,11 @@ impl TryReadError { } } -/// The error type of fallible casts to unaligned types. +/// The error type of well-aligned, fallible casts. /// -/// This is like [`TryCastError`], but for unaligned types. It is identical to -/// `TryCastError`, except that its alignment error is [`Infallible`]. +/// This is like [`TryCastError`], but for casts that are always well-aligned. +/// It is identical to `TryCastError`, except that its alignment error is +/// [`Infallible`]. /// /// As of this writing, none of zerocopy's API produces this error directly. /// However, it is useful since it permits users to infallibly discard alignment @@ -906,7 +917,7 @@ impl TryReadError { /// } /// /// impl Bools { -/// fn parse(bytes: &[u8]) -> Result<&Bools, UnalignedTryCastError<&[u8], Bools>> { +/// fn parse(bytes: &[u8]) -> Result<&Bools, AlignedTryCastError<&[u8], Bools>> { /// // Since `Bools: Unaligned`, we can infallibly discard /// // the alignment error. /// Bools::try_ref_from_bytes(bytes).map_err(Into::into) @@ -914,7 +925,7 @@ impl TryReadError { /// } /// ``` #[allow(type_alias_bounds)] -pub type UnalignedTryCastError = +pub type AlignedTryCastError = ConvertError, ValidityError>; /// The error type of a failed allocation. diff --git a/src/lib.rs b/src/lib.rs index c3aff4e9b2..f64e36b72c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1340,17 +1340,20 @@ pub unsafe trait TryFromBytes { candidate: Maybe<'_, Self, A>, ) -> bool; - /// Attempts to interpret the given `source` as a `&Self` without copying. + /// Attempts to interpret the given `source` as a `&Self`. /// /// If the bytes of `source` are a valid instance of `Self`, this method /// returns a reference to those bytes interpreted as a `Self`. If the /// length of `source` is not a [valid size of `Self`][valid-size], or if /// `source` is not appropriately aligned, or if `source` is not a valid - /// instance of `Self`, this returns `Err`. + /// instance of `Self`, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][ConvertError::from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -1438,8 +1441,7 @@ pub unsafe trait TryFromBytes { } } - /// Attempts to interpret the prefix of the given `source` as a `&Self` - /// without copying. + /// Attempts to interpret the prefix of the given `source` as a `&Self`. /// /// This method computes the [largest possible size of `Self`][valid-size] /// that can fit in the leading bytes of `source`. If that prefix is a valid @@ -1447,10 +1449,13 @@ pub unsafe trait TryFromBytes { /// interpreted as `Self`, and a reference to the remaining bytes. If there /// are insufficient bytes, or if `source` is not appropriately aligned, or /// if those bytes are not a valid instance of `Self`, this returns `Err`. + /// If [`Self: Unaligned`][self-unaligned], you can [infallibly discard the + /// alignment error][ConvertError::from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -1522,8 +1527,7 @@ pub unsafe trait TryFromBytes { try_ref_from_prefix_suffix(source, CastType::Prefix, None) } - /// Attempts to interpret the suffix of the given `source` as a `&Self` - /// without copying. + /// Attempts to interpret the suffix of the given `source` as a `&Self`. /// /// This method computes the [largest possible size of `Self`][valid-size] /// that can fit in the trailing bytes of `source`. If that suffix is a @@ -1531,11 +1535,13 @@ pub unsafe trait TryFromBytes { /// interpreted as `Self`, and a reference to the preceding bytes. If there /// are insufficient bytes, or if the suffix of `source` would not be /// appropriately aligned, or if the suffix is not a valid instance of - /// `Self`, this returns `Err`. + /// `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned], you + /// can [infallibly discard the alignment error][ConvertError::from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -1614,11 +1620,14 @@ pub unsafe trait TryFromBytes { /// returns a reference to those bytes interpreted as a `Self`. If the /// length of `source` is not a [valid size of `Self`][valid-size], or if /// `source` is not appropriately aligned, or if `source` is not a valid - /// instance of `Self`, this returns `Err`. + /// instance of `Self`, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][ConvertError::from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -1708,18 +1717,21 @@ pub unsafe trait TryFromBytes { } /// Attempts to interpret the prefix of the given `source` as a `&mut - /// Self` without copying. + /// Self`. /// /// This method computes the [largest possible size of `Self`][valid-size] - /// that can fit in the leading bytes of `source`. If that prefix is a - /// valid instance of `Self`, this method returns a reference to those bytes + /// that can fit in the leading bytes of `source`. 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 `source` is not appropriately aligned, - /// or if the bytes are not a valid instance of `Self`, this returns `Err`. + /// are insufficient bytes, or if `source` is not appropriately aligned, or + /// if the bytes are not a valid instance of `Self`, this returns `Err`. If + /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the + /// alignment error][ConvertError::from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -1800,7 +1812,7 @@ pub unsafe trait TryFromBytes { } /// Attempts to interpret the suffix of the given `source` as a `&mut - /// Self` without copying. + /// Self`. /// /// This method computes the [largest possible size of `Self`][valid-size] /// that can fit in the trailing bytes of `source`. If that suffix is a @@ -1808,11 +1820,13 @@ pub unsafe trait TryFromBytes { /// interpreted as `Self`, and a reference to the preceding bytes. If there /// are insufficient bytes, or if the suffix of `source` would not be /// appropriately aligned, or if the suffix is not a valid instance of - /// `Self`, this returns `Err`. + /// `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned], you + /// can [infallibly discard the alignment error][ConvertError::from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -2697,16 +2711,19 @@ pub unsafe trait FromBytes: FromZeros { where Self: Sized; - /// Interprets the given `source` as a `&Self` without copying. + /// Interprets the given `source` as a `&Self`. /// /// 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`][valid-size], or if `source` is not appropriately aligned, this - /// returns `Err`. + /// returns `Err`. If [`Self: Unaligned`][self-unaligned], you can + /// [infallibly discard the alignment error][size-error-from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -2782,11 +2799,15 @@ pub unsafe trait FromBytes: FromZeros { /// 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`. + /// is not appropriately aligned, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -2856,17 +2877,21 @@ pub unsafe trait FromBytes: FromZeros { 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`. /// /// This method computes the [largest possible size of `Self`][valid-size] /// 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`. + /// suffix of `source` is not appropriately aligned, this returns `Err`. If + /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the + /// alignment error][size-error-from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -2922,16 +2947,19 @@ pub unsafe trait FromBytes: FromZeros { ref_from_prefix_suffix(source, None, CastType::Suffix).map(swap) } - /// Interprets the given `source` as a `&mut Self` without copying. + /// Interprets the given `source` as a `&mut Self`. /// /// 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`][valid-size], or if `source` is not appropriately aligned, this - /// returns `Err`. + /// returns `Err`. If [`Self: Unaligned`][self-unaligned], you can + /// [infallibly discard the alignment error][size-error-from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -3007,11 +3035,15 @@ pub unsafe trait FromBytes: FromZeros { /// 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`. + /// is not appropriately aligned, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -3088,11 +3120,15 @@ pub unsafe trait FromBytes: FromZeros { /// 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`. + /// suffix of `source` is not appropriately aligned, this returns `Err`. If + /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the + /// alignment error][size-error-from]. /// /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -3159,7 +3195,12 @@ pub unsafe trait FromBytes: FromZeros { /// 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`. + /// appropriately aligned, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. + /// + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Examples /// @@ -3227,12 +3268,17 @@ pub unsafe trait FromBytes: FromZeros { } /// Interprets the prefix of the given `source` as a DST `&Self` with length - /// equal to `count` without copying. + /// equal to `count`. /// /// 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`. + /// is not appropriately aligned, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. + /// + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Examples /// @@ -3297,12 +3343,17 @@ pub unsafe trait FromBytes: FromZeros { } /// Interprets the suffix of the given `source` as a DST `&Self` with length - /// equal to `count` without copying. + /// equal to `count`. /// /// 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`. + /// suffix of `source` is not appropriately aligned, this returns `Err`. If + /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the + /// alignment error][size-error-from]. + /// + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Examples /// @@ -3372,7 +3423,12 @@ pub unsafe trait FromBytes: FromZeros { /// 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`. + /// appropriately aligned, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. + /// + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Examples /// @@ -3443,12 +3499,17 @@ pub unsafe trait FromBytes: FromZeros { } /// Interprets the prefix of the given `source` as a `&mut Self` with DST - /// length equal to `count` without copying. + /// length equal to `count`. /// /// 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`. + /// is not appropriately aligned, this returns `Err`. If [`Self: + /// Unaligned`][self-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. + /// + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Examples /// @@ -3518,12 +3579,17 @@ pub unsafe trait FromBytes: FromZeros { } /// Interprets the suffix of the given `source` as a `&mut Self` with DST - /// length equal to `count` without copying. + /// length equal to `count`. /// /// 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`. + /// suffix of `source` is not appropriately aligned, this returns `Err`. If + /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the + /// alignment error][size-error-from]. + /// + /// [self-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Examples /// @@ -3836,7 +3902,7 @@ pub unsafe trait FromBytes: FromZeros { } } -/// Interprets the given affix of the given bytes as a `&Self` without copying. +/// Interprets the given affix of the given bytes as a `&Self`. /// /// 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 diff --git a/src/ref.rs b/src/ref.rs index 7fdd8fe158..6e646e6634 100644 --- a/src/ref.rs +++ b/src/ref.rs @@ -265,11 +265,15 @@ where /// Constructs a `Ref` from a byte slice. /// /// If the length of `source` is not a [valid size of `T`][valid-size], or - /// if `source` is not appropriately aligned for `T`, this returns `Err`. + /// if `source` is not appropriately aligned for `T`, this returns `Err`. If + /// [`T: Unaligned`][t-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. /// /// `T` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [t-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -316,11 +320,14 @@ where /// 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`. + /// this returns `Err`. If [`T: Unaligned`][t-unaligned], you can + /// [infallibly discard the alignment error][size-error-from]. /// /// `T` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [t-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -377,11 +384,15 @@ where /// 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`. + /// appropriately aligned, this returns `Err`. If [`T: + /// Unaligned`][t-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. /// /// `T` may be a sized type, a slice, or a [slice DST][slice-dst]. /// /// [valid-size]: crate#what-is-a-valid-size + /// [t-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// [slice-dst]: KnownLayout#dynamically-sized-types /// /// # Compile-Time Assertions @@ -440,7 +451,11 @@ where /// 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`. + /// aligned, this returns `Err`. If [`T: Unaligned`][t-unaligned], you can + /// [infallibly discard the alignment error][size-error-from]. + /// + /// [t-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Compile-Time Assertions /// @@ -486,7 +501,12 @@ where /// 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`. + /// not appropriately aligned, this returns `Err`. If [`T: + /// Unaligned`][t-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. + /// + /// [t-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Compile-Time Assertions /// @@ -527,7 +547,12 @@ where /// 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`. + /// of `source` is not appropriately aligned, this returns `Err`. If [`T: + /// Unaligned`][t-unaligned], you can [infallibly discard the alignment + /// error][size-error-from]. + /// + /// [t-unaligned]: Unaligned + /// [size-error-from]: error/struct.SizeError.html#method.from-1 /// /// # Compile-Time Assertions ///