xref: /linux/rust/zerocopy/src/ref.rs (revision 7c306f00835a237a70024a8f968dbc3bc8db8fcf)
1 // SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
2 //
3 // Copyright 2024 The Fuchsia Authors
4 //
5 // Licensed under the 2-Clause BSD License <LICENSE-BSD or
6 // https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0
7 // <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
8 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
9 // This file may not be copied, modified, or distributed except according to
10 // those terms.
11 use super::*;
12 use crate::pointer::{
13     BecauseMutationCompatible, BecauseSharedCompatible, MutationCompatible, TransmuteFromPtr,
14 };
15 
16 mod def {
17     use core::marker::PhantomData;
18 
19     use crate::{
20         ByteSlice, ByteSliceMut, CloneableByteSlice, CopyableByteSlice, IntoByteSlice,
21         IntoByteSliceMut, KnownLayout, PointerMetadata,
22     };
23 
24     /// A typed reference derived from a byte slice.
25     ///
26     /// A `Ref<B, T>` is a reference to a `T` which is stored in a byte slice, `B`.
27     /// Unlike a native reference (`&T` or `&mut T`), `Ref<B, T>` has the same
28     /// mutability as the byte slice it was constructed from (`B`).
29     ///
30     /// # Examples
31     ///
32     /// `Ref` can be used to treat a sequence of bytes as a structured type, and
33     /// to read and write the fields of that type as if the byte slice reference
34     /// were simply a reference to that type.
35     ///
36     /// ```rust
37     /// use zerocopy::*;
38     /// # use zerocopy_derive::*;
39     ///
40     /// #[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
41     /// #[repr(C)]
42     /// struct UdpHeader {
43     ///     src_port: [u8; 2],
44     ///     dst_port: [u8; 2],
45     ///     length: [u8; 2],
46     ///     checksum: [u8; 2],
47     /// }
48     ///
49     /// #[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
50     /// #[repr(C, packed)]
51     /// struct UdpPacket {
52     ///     header: UdpHeader,
53     ///     body: [u8],
54     /// }
55     ///
56     /// impl UdpPacket {
57     ///     pub fn parse<B: ByteSlice>(bytes: B) -> Option<Ref<B, UdpPacket>> {
58     ///         Ref::from_bytes(bytes).ok()
59     ///     }
60     /// }
61     /// ```
62     pub struct Ref<B, T: ?Sized> {
63         // INVARIANTS:
64         // - The referent (via `.deref`, `.deref_mut`, `.into`) byte slice is
65         //   aligned to `T`'s alignment, and its size is valid for `T`.
66         // - If `T: KnownLayout`, let `metadata` be
67         //   `T::PointerMetadata::from_elem_count` applied to `elem_count`.
68         //   Then `T::size_for_metadata(metadata)` is `Some(referent.len())`.
69         bytes: B,
70         // Ignored when `T` does not implement `KnownLayout`.
71         elem_count: usize,
72         _marker: PhantomData<T>,
73     }
74 
75     impl<B, T> Ref<B, T> {
76         /// Constructs a new `Ref` to a sized `T`.
77         ///
78         /// # Safety
79         ///
80         /// `bytes` dereferences (via [`deref`], [`deref_mut`], and [`into`]) to
81         /// a byte slice which is aligned to `T`'s alignment and whose size is
82         /// `size_of::<T>()`.
83         ///
84         /// [`deref`]: core::ops::Deref::deref
85         /// [`deref_mut`]: core::ops::DerefMut::deref_mut
86         /// [`into`]: core::convert::Into::into
87         pub(super) unsafe fn new_sized_unchecked(bytes: B) -> Ref<B, T> {
88             // INVARIANTS: The caller has promised that `bytes`'s referent is
89             // validly aligned and has size `size_of::<T>()`. If `T:
90             // KnownLayout`, then, since `T` is sized, `T::PointerMetadata` is
91             // `()`. `from_elem_count` returns `()` for any element count, and
92             // `T::size_for_metadata(()) == Some(size_of::<T>())`. `size_of`
93             // reports this size in bytes [1].
94             //
95             // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of.html:
96             //
97             //     Returns the size of a type in bytes.
98             Ref { bytes, elem_count: 0, _marker: PhantomData }
99         }
100     }
101 
102     impl<B, T: KnownLayout + ?Sized> Ref<B, T> {
103         /// Constructs a new `Ref`.
104         ///
105         /// # Safety
106         ///
107         /// `bytes` dereferences (via [`deref`], [`deref_mut`], and [`into`]) to
108         /// a byte slice which is aligned to `T`'s alignment and satisfies
109         /// `T::size_for_metadata(metadata) == Some(referent.len())`.
110         ///
111         /// [`deref`]: core::ops::Deref::deref
112         /// [`deref_mut`]: core::ops::DerefMut::deref_mut
113         /// [`into`]: core::convert::Into::into
114         pub(super) unsafe fn new_unchecked(bytes: B, metadata: T::PointerMetadata) -> Ref<B, T> {
115             // INVARIANTS: The caller has promised that `bytes`'s referent is
116             // validly aligned and has exactly the size described by `metadata`.
117             // `KnownLayout::PointerMetadata` is `()` for sized types and
118             // `usize` for slice DSTs. For both permitted metadata types,
119             // `from_elem_count(metadata.to_elem_count()) == metadata`: `()`
120             // round-trips through zero, while `usize` round-trips through
121             // itself. Thus, storing the element count preserves the metadata
122             // whose size the caller validated. This agrees with Rust's
123             // language-level definition of slice pointer metadata [1].
124             //
125             // [1] Per https://doc.rust-lang.org/1.56.0/reference/dynamically-sized-types.html:
126             //
127             //     Pointers to slices also store the number of elements of the
128             //     slice.
129             Ref { bytes, elem_count: metadata.to_elem_count(), _marker: PhantomData }
130         }
131 
132         /// Gets the pointer metadata represented by this `Ref`.
133         #[inline(always)]
134         pub(super) fn pointer_metadata(&self) -> T::PointerMetadata {
135             // INVARIANTS: `KnownLayout::PointerMetadata` is either `()` or
136             // `usize`. For `()`, `from_elem_count` ignores the element count;
137             // for `usize`, it returns the element count unchanged.
138             T::PointerMetadata::from_elem_count(self.elem_count)
139         }
140     }
141 
142     impl<B: ByteSlice, T: ?Sized> Ref<B, T> {
143         /// Access the byte slice as a [`ByteSlice`].
144         ///
145         /// # Safety
146         ///
147         /// The caller promises not to call methods on the returned
148         /// [`ByteSlice`] other than `ByteSlice` methods (for example, via
149         /// `Any::downcast_ref`).
150         ///
151         /// `as_byte_slice` promises to return a `ByteSlice` whose referent is
152         /// validly aligned for `T` and has a valid size for `T`. If `T:
153         /// KnownLayout`, then `T::size_for_metadata(self.pointer_metadata())`
154         /// returns `Some(referent.len())`.
155         pub(crate) unsafe fn as_byte_slice(&self) -> &impl ByteSlice {
156             // INVARIANTS: The caller promises not to call methods other than
157             // those on `ByteSlice`. Since `B: ByteSlice`, dereference stability
158             // guarantees that calling `ByteSlice` methods will not change the
159             // address or length of `self.bytes`'s referent.
160             //
161             // SAFETY: By invariant on `self`, the alignment, size, and metadata
162             // postconditions are upheld.
163             &self.bytes
164         }
165     }
166 
167     impl<B: ByteSliceMut, T: ?Sized> Ref<B, T> {
168         /// Access the byte slice as a [`ByteSliceMut`].
169         ///
170         /// # Safety
171         ///
172         /// The caller promises not to call methods on the returned
173         /// [`ByteSliceMut`] other than `ByteSliceMut` methods (for example, via
174         /// `Any::downcast_mut`).
175         ///
176         /// `as_byte_slice_mut` promises to return a `ByteSliceMut` whose
177         /// referent is validly aligned for `T` and has a valid size for `T`. If
178         /// `T: KnownLayout`, then
179         /// `T::size_for_metadata(self.pointer_metadata())` returns
180         /// `Some(referent.len())`.
181         pub(crate) unsafe fn as_byte_slice_mut(&mut self) -> &mut impl ByteSliceMut {
182             // INVARIANTS: The caller promises not to call methods other than
183             // those on `ByteSliceMut`. Since `B: ByteSlice`, dereference
184             // stability guarantees that calling `ByteSlice` methods will not
185             // change the address or length of `self.bytes`'s referent.
186             //
187             // SAFETY: By invariant on `self`, the alignment, size, and metadata
188             // postconditions are upheld.
189             &mut self.bytes
190         }
191     }
192 
193     impl<'a, B: IntoByteSlice<'a>, T: ?Sized> Ref<B, T> {
194         /// Access the byte slice as an [`IntoByteSlice`].
195         ///
196         /// # Safety
197         ///
198         /// The caller promises not to call methods on the returned
199         /// [`IntoByteSlice`] other than `IntoByteSlice` methods (for example,
200         /// via `Any::downcast_ref`).
201         ///
202         /// `into_byte_slice` promises to return an `IntoByteSlice` whose
203         /// referent is validly aligned for `T` and has a valid size for `T`. If
204         /// `T: KnownLayout`, then
205         /// `T::size_for_metadata(self.pointer_metadata())` returns
206         /// `Some(referent.len())`.
207         pub(crate) unsafe fn into_byte_slice(self) -> impl IntoByteSlice<'a> {
208             // INVARIANTS: The caller promises not to call methods other than
209             // those on `IntoByteSlice`. Since `B: ByteSlice`, dereference
210             // stability guarantees that calling `ByteSlice` methods will not
211             // change the address or length of `self.bytes`'s referent.
212             //
213             // SAFETY: By invariant on `self`, the alignment, size, and metadata
214             // postconditions are upheld.
215             self.bytes
216         }
217     }
218 
219     impl<'a, B: IntoByteSliceMut<'a>, T: ?Sized> Ref<B, T> {
220         /// Access the byte slice as an [`IntoByteSliceMut`].
221         ///
222         /// # Safety
223         ///
224         /// The caller promises not to call methods on the returned
225         /// [`IntoByteSliceMut`] other than `IntoByteSliceMut` methods (for
226         /// example, via `Any::downcast_mut`).
227         ///
228         /// `into_byte_slice_mut` promises to return an `IntoByteSliceMut` whose
229         /// referent is validly aligned for `T` and has a valid size for `T`. If
230         /// `T: KnownLayout`, then
231         /// `T::size_for_metadata(self.pointer_metadata())` returns
232         /// `Some(referent.len())`.
233         pub(crate) unsafe fn into_byte_slice_mut(self) -> impl IntoByteSliceMut<'a> {
234             // INVARIANTS: The caller promises not to call methods other than
235             // those on `IntoByteSliceMut`. Since `B: ByteSlice`, dereference
236             // stability guarantees that calling `ByteSlice` methods will not
237             // change the address or length of `self.bytes`'s referent.
238             //
239             // SAFETY: By invariant on `self`, the alignment, size, and metadata
240             // postconditions are upheld.
241             self.bytes
242         }
243     }
244 
245     impl<B: CloneableByteSlice + Clone, T: ?Sized> Clone for Ref<B, T> {
246         #[inline]
247         fn clone(&self) -> Ref<B, T> {
248             // INVARIANTS: Since `B: CloneableByteSlice`, `self.bytes.clone()` has
249             // the same address and length as `self.bytes`. We copy
250             // `self.elem_count`, so the clone also has the same metadata. Since
251             // `self` upholds the field invariants, so does the clone.
252             Ref { bytes: self.bytes.clone(), elem_count: self.elem_count, _marker: PhantomData }
253         }
254     }
255 
256     // INVARIANTS: Since `B: CopyableByteSlice`, the copied `Ref`'s `bytes` has the
257     // same address and length as the original `Ref`'s `bytes`. The copied
258     // `elem_count` has the same metadata. Since the original upholds the field
259     // invariants, so does the copy.
260     impl<B: CopyableByteSlice + Copy, T: ?Sized> Copy for Ref<B, T> {}
261 }
262 
263 #[allow(unreachable_pub)] // This is a false positive on our MSRV toolchain.
264 pub use def::Ref;
265 
266 use crate::pointer::{
267     invariant::{Aligned, BecauseExclusive, Initialized, Safe, Unaligned},
268     BecauseRead, PtrInner,
269 };
270 
271 impl<B, T> Ref<B, T>
272 where
273     B: ByteSlice,
274 {
275     #[must_use = "has no side effects"]
276     pub(crate) fn sized_from(bytes: B) -> Result<Ref<B, T>, CastError<B, T>> {
277         if bytes.len() != mem::size_of::<T>() {
278             return Err(SizeError::new(bytes).into());
279         }
280         if let Err(err) = util::validate_aligned_to::<_, T>(bytes.deref()) {
281             return Err(err.with_src(bytes).into());
282         }
283 
284         // SAFETY: `size_of` returns `T`'s size in bytes [1]. The equality check
285         // above therefore establishes that `bytes` has exactly that byte
286         // length, and `validate_aligned_to` establishes alignment.
287         //
288         // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of.html:
289         //
290         //     Returns the size of a type in bytes.
291         Ok(unsafe { Ref::new_sized_unchecked(bytes) })
292     }
293 }
294 
295 impl<B, T> Ref<B, T>
296 where
297     B: SplitByteSlice,
298 {
299     #[must_use = "has no side effects"]
300     pub(crate) fn sized_from_prefix(bytes: B) -> Result<(Ref<B, T>, B), CastError<B, T>> {
301         if bytes.len() < mem::size_of::<T>() {
302             return Err(SizeError::new(bytes).into());
303         }
304         if let Err(err) = util::validate_aligned_to::<_, T>(bytes.deref()) {
305             return Err(err.with_src(bytes).into());
306         }
307         let (bytes, suffix) = bytes.split_at(mem::size_of::<T>()).map_err(
308             #[inline(always)]
309             |b| SizeError::new(b).into(),
310         )?;
311         // SAFETY: We just validated alignment and that `bytes` is at least as
312         // large as `T`. `bytes.split_at(mem::size_of::<T>())?` ensures that the
313         // new `bytes` is exactly the size of `T`, measured in bytes as specified
314         // for `size_of` [1]. By safety postcondition on
315         // `SplitByteSlice::split_at` we can rely on `split_at` to produce the
316         // correct `bytes` and `suffix`.
317         //
318         // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of.html:
319         //
320         //     Returns the size of a type in bytes.
321         let r = unsafe { Ref::new_sized_unchecked(bytes) };
322         Ok((r, suffix))
323     }
324 
325     #[must_use = "has no side effects"]
326     pub(crate) fn sized_from_suffix(bytes: B) -> Result<(B, Ref<B, T>), CastError<B, T>> {
327         let bytes_len = bytes.len();
328         let split_at = if let Some(split_at) = bytes_len.checked_sub(mem::size_of::<T>()) {
329             split_at
330         } else {
331             return Err(SizeError::new(bytes).into());
332         };
333         let (prefix, bytes) = bytes.split_at(split_at).map_err(|b| SizeError::new(b).into())?;
334         if let Err(err) = util::validate_aligned_to::<_, T>(bytes.deref()) {
335             return Err(err.with_src(bytes).into());
336         }
337         // SAFETY: Since `split_at` is defined as `bytes_len - size_of::<T>()`,
338         // the `bytes` which results from `let (prefix, bytes) =
339         // bytes.split_at(split_at)?` has length `size_of::<T>()`, measured in
340         // bytes as specified for `size_of` [1]. After constructing `bytes`, we
341         // validate that it has the proper alignment. By safety postcondition on
342         // `SplitByteSlice::split_at` we can rely on `split_at` to produce the
343         // correct `prefix` and `bytes`.
344         //
345         // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of.html:
346         //
347         //     Returns the size of a type in bytes.
348         let r = unsafe { Ref::new_sized_unchecked(bytes) };
349         Ok((prefix, r))
350     }
351 }
352 
353 impl<B, T> Ref<B, T>
354 where
355     B: ByteSlice,
356     T: KnownLayout + Immutable + ?Sized,
357 {
358     /// Constructs a `Ref` from a byte slice.
359     ///
360     /// If the length of `source` is not a [valid size of `T`][valid-size], or
361     /// if `source` is not appropriately aligned for `T`, this returns `Err`. If
362     /// [`T: Unaligned`][t-unaligned], you can [infallibly discard the alignment
363     /// error][size-error-from].
364     ///
365     /// `T` may be a sized type, a slice, or a [slice DST][slice-dst].
366     ///
367     /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
368     /// [t-unaligned]: crate::Unaligned
369     /// [size-error-from]: error/struct.SizeError.html#method.from-1
370     /// [slice-dst]: KnownLayout#dynamically-sized-types
371     ///
372     /// # Compile-Time Assertions
373     ///
374     /// This method cannot yet be used on unsized types whose dynamically-sized
375     /// component is zero-sized. Attempting to use this method on such types
376     /// results in a compile-time assertion error; e.g.:
377     ///
378     /// ```compile_fail,E0080
379     /// use zerocopy::*;
380     /// # use zerocopy_derive::*;
381     ///
382     /// #[derive(Immutable, KnownLayout)]
383     /// #[repr(C)]
384     /// struct ZSTy {
385     ///     leading_sized: u16,
386     ///     trailing_dst: [()],
387     /// }
388     ///
389     /// let _ = Ref::<_, ZSTy>::from_bytes(&b"UU"[..]); // ⚠ Compile Error!
390     /// ```
391     ///
392     #[doc = codegen_section!(
393         header = "h5",
394         bench = "ref_type_from_bytes",
395         format = "coco",
396         arity = 3,
397         [
398             open
399             @index 1
400             @title "Sized"
401             @variant "static_size"
402         ],
403         [
404             @index 2
405             @title "Unsized"
406             @variant "dynamic_size"
407         ],
408         [
409             @index 3
410             @title "Dynamically Padded"
411             @variant "dynamic_padding"
412         ]
413     )]
414     #[must_use = "has no side effects"]
415     #[inline]
416     pub fn from_bytes(source: B) -> Result<Ref<B, T>, CastError<B, T>> {
417         static_assert_dst_is_not_zst!(T);
418         let metadata = match Ptr::from_ref(source.deref())
419             .try_cast_into_no_leftover::<T, BecauseImmutable>(None)
420         {
421             Ok(ptr) => T::pointer_to_metadata(ptr.as_inner().as_ptr()),
422             Err(e) => return Err(e.with_src(()).with_src(source)),
423         };
424         // SAFETY: By its safety postcondition, `try_cast_into_no_leftover`
425         // returned a `Ptr<T>` aligned as required for references [2], over the
426         // same byte range as `source.deref()`. `pointer_to_metadata` returns
427         // the metadata stored in that pointer, and `size_for_metadata` computes
428         // the corresponding dynamically-known byte size [1]. Thus,
429         // `T::size_for_metadata(metadata)` is `Some(source.len())`.
430         // `ByteSlice` and its applicable subtraits guarantee that the stored
431         // `source` continues to dereference or convert to that address and
432         // length. These facts establish both preconditions of `new_unchecked`.
433         //
434         // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of_val.html:
435         //
436         //     Returns the size of the pointed-to value in bytes.
437         //
438         //     ... when `T` has no statically-known size ... `size_of_val` can
439         //     be used to get the dynamically-known size.
440         //
441         // [2] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.align_of_val.html:
442         //
443         //     Returns the ABI-required minimum alignment of the type of the
444         //     value that `val` points to.
445         //
446         //     Every reference to a value of the type `T` must be a multiple of
447         //     this number.
448         Ok(unsafe { Ref::new_unchecked(source, metadata) })
449     }
450 }
451 
452 impl<B, T> Ref<B, T>
453 where
454     B: SplitByteSlice,
455     T: KnownLayout + Immutable + ?Sized,
456 {
457     /// Constructs a `Ref` from the prefix of a byte slice.
458     ///
459     /// This method computes the [largest possible size of `T`][valid-size] that
460     /// can fit in the leading bytes of `source`, then attempts to return both a
461     /// `Ref` to those bytes, and a reference to the remaining bytes. If there
462     /// are insufficient bytes, or if `source` is not appropriately aligned,
463     /// this returns `Err`. If [`T: Unaligned`][t-unaligned], you can
464     /// [infallibly discard the alignment error][size-error-from].
465     ///
466     /// `T` may be a sized type, a slice, or a [slice DST][slice-dst].
467     ///
468     /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
469     /// [t-unaligned]: crate::Unaligned
470     /// [size-error-from]: error/struct.SizeError.html#method.from-1
471     /// [slice-dst]: KnownLayout#dynamically-sized-types
472     ///
473     /// # Compile-Time Assertions
474     ///
475     /// This method cannot yet be used on unsized types whose dynamically-sized
476     /// component is zero-sized. Attempting to use this method on such types
477     /// results in a compile-time assertion error; e.g.:
478     ///
479     /// ```compile_fail,E0080
480     /// use zerocopy::*;
481     /// # use zerocopy_derive::*;
482     ///
483     /// #[derive(Immutable, KnownLayout)]
484     /// #[repr(C)]
485     /// struct ZSTy {
486     ///     leading_sized: u16,
487     ///     trailing_dst: [()],
488     /// }
489     ///
490     /// let _ = Ref::<_, ZSTy>::from_prefix(&b"UU"[..]); // ⚠ Compile Error!
491     /// ```
492     ///
493     #[doc = codegen_section!(
494         header = "h5",
495         bench = "ref_type_from_prefix",
496         format = "coco",
497         arity = 3,
498         [
499             open
500             @index 1
501             @title "Sized"
502             @variant "static_size"
503         ],
504         [
505             @index 2
506             @title "Unsized"
507             @variant "dynamic_size"
508         ],
509         [
510             @index 3
511             @title "Dynamically Padded"
512             @variant "dynamic_padding"
513         ]
514     )]
515     #[must_use = "has no side effects"]
516     #[inline]
517     pub fn from_prefix(source: B) -> Result<(Ref<B, T>, B), CastError<B, T>> {
518         static_assert_dst_is_not_zst!(T);
519         let (metadata, remainder) = match Ptr::from_ref(source.deref())
520             .try_cast_into::<T, BecauseImmutable>(CastType::Prefix, None)
521         {
522             Ok((ptr, remainder)) => (T::pointer_to_metadata(ptr.as_inner().as_ptr()), remainder),
523             Err(e) => {
524                 return Err(e.with_src(()).with_src(source));
525             }
526         };
527 
528         // SAFETY: `remainder` is constructed as a subset of `source`, and so it
529         // cannot have a larger size than `source`. Both of their `len` methods
530         // measure bytes (`source` deref's to `[u8]`, and `remainder` is a
531         // `Ptr<[u8]>`), so `source.len() >= remainder.len()`. Thus, this cannot
532         // underflow.
533         #[allow(unstable_name_collisions)]
534         let split_at = unsafe { source.len().unchecked_sub(remainder.len()) };
535         let (bytes, suffix) = source.split_at(split_at).map_err(|b| SizeError::new(b).into())?;
536         // SAFETY: By its safety postcondition, `try_cast_into` returned an
537         // `Ptr<T>` aligned as required for references [2], and a remainder
538         // which are non-overlapping, cover `source.deref()`, and place the
539         // `Ptr<T>` at `source.deref()`'s address.
540         // Therefore, `split_at` is the typed pointer's byte length. By the
541         // safety postcondition of `SplitByteSlice::split_at`, `bytes` has that
542         // length and address. `pointer_to_metadata` returns the metadata stored
543         // in the typed pointer, and `size_for_metadata` computes the
544         // corresponding dynamically-known byte size [1]. Thus,
545         // `T::size_for_metadata(metadata)` is `Some(bytes.len())`. The
546         // `SplitByteSlice` and `ByteSlice` contracts preserve the established
547         // address and length, satisfying both preconditions of
548         // `new_unchecked`.
549         //
550         // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of_val.html:
551         //
552         //     Returns the size of the pointed-to value in bytes.
553         //
554         //     ... when `T` has no statically-known size ... `size_of_val` can
555         //     be used to get the dynamically-known size.
556         //
557         // [2] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.align_of_val.html:
558         //
559         //     Returns the ABI-required minimum alignment of the type of the
560         //     value that `val` points to.
561         //
562         //     Every reference to a value of the type `T` must be a multiple of
563         //     this number.
564         let r = unsafe { Ref::new_unchecked(bytes, metadata) };
565         Ok((r, suffix))
566     }
567 
568     /// Constructs a `Ref` from the suffix of a byte slice.
569     ///
570     /// This method computes the [largest possible size of `T`][valid-size] that
571     /// can fit in the trailing bytes of `source`, then attempts to return both
572     /// a `Ref` to those bytes, and a reference to the preceding bytes. If there
573     /// are insufficient bytes, or if that suffix of `source` is not
574     /// appropriately aligned, this returns `Err`. If [`T:
575     /// Unaligned`][t-unaligned], you can [infallibly discard the alignment
576     /// error][size-error-from].
577     ///
578     /// `T` may be a sized type, a slice, or a [slice DST][slice-dst].
579     ///
580     /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
581     /// [t-unaligned]: crate::Unaligned
582     /// [size-error-from]: error/struct.SizeError.html#method.from-1
583     /// [slice-dst]: KnownLayout#dynamically-sized-types
584     ///
585     /// # Compile-Time Assertions
586     ///
587     /// This method cannot yet be used on unsized types whose dynamically-sized
588     /// component is zero-sized. Attempting to use this method on such types
589     /// results in a compile-time assertion error; e.g.:
590     ///
591     /// ```compile_fail,E0080
592     /// use zerocopy::*;
593     /// # use zerocopy_derive::*;
594     ///
595     /// #[derive(Immutable, KnownLayout)]
596     /// #[repr(C)]
597     /// struct ZSTy {
598     ///     leading_sized: u16,
599     ///     trailing_dst: [()],
600     /// }
601     ///
602     /// let _ = Ref::<_, ZSTy>::from_suffix(&b"UU"[..]); // ⚠ Compile Error!
603     /// ```
604     ///
605     #[doc = codegen_section!(
606         header = "h5",
607         bench = "ref_type_from_suffix",
608         format = "coco",
609         arity = 3,
610         [
611             open
612             @index 1
613             @title "Sized"
614             @variant "static_size"
615         ],
616         [
617             @index 2
618             @title "Unsized"
619             @variant "dynamic_size"
620         ],
621         [
622             @index 3
623             @title "Dynamically Padded"
624             @variant "dynamic_padding"
625         ]
626     )]
627     #[must_use = "has no side effects"]
628     #[inline]
629     pub fn from_suffix(source: B) -> Result<(B, Ref<B, T>), CastError<B, T>> {
630         static_assert_dst_is_not_zst!(T);
631         let (metadata, remainder) = match Ptr::from_ref(source.deref())
632             .try_cast_into::<T, BecauseImmutable>(CastType::Suffix, None)
633         {
634             Ok((ptr, remainder)) => (T::pointer_to_metadata(ptr.as_inner().as_ptr()), remainder),
635             Err(e) => {
636                 let e = e.with_src(());
637                 return Err(e.with_src(source));
638             }
639         };
640 
641         let split_at = remainder.len();
642         let (prefix, bytes) = source.split_at(split_at).map_err(|b| SizeError::new(b).into())?;
643         // SAFETY: By its safety postcondition, `try_cast_into` returned an
644         // `Ptr<T>` aligned as required for references [2], and a remainder
645         // which are non-overlapping, cover `source.deref()`, and place the
646         // remainder at `source.deref()`'s address. More precisely,
647         // `PtrInner::try_cast_into` constructs the typed suffix from the
648         // `r_slice` produced by `split_at_unchecked(split_at)` and returns its
649         // `l_slice` as `remainder`. Thus, even when `T` is zero-sized, the typed
650         // pointer and the `bytes` produced by splitting `source` at
651         // `remainder.len()` have the same address and length. By the safety
652         // postcondition of `SplitByteSlice::split_at`, `bytes` retains that
653         // address and length. `pointer_to_metadata` returns the metadata stored
654         // in the typed pointer, and `size_for_metadata` computes the
655         // corresponding dynamically-known byte size [1]. Thus,
656         // `T::size_for_metadata(metadata)` is `Some(bytes.len())`. The
657         // `SplitByteSlice` and `ByteSlice` contracts preserve the established
658         // address and length, satisfying both preconditions of
659         // `new_unchecked`.
660         //
661         // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of_val.html:
662         //
663         //     Returns the size of the pointed-to value in bytes.
664         //
665         //     ... when `T` has no statically-known size ... `size_of_val` can
666         //     be used to get the dynamically-known size.
667         //
668         // [2] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.align_of_val.html:
669         //
670         //     Returns the ABI-required minimum alignment of the type of the
671         //     value that `val` points to.
672         //
673         //     Every reference to a value of the type `T` must be a multiple of
674         //     this number.
675         let r = unsafe { Ref::new_unchecked(bytes, metadata) };
676         Ok((prefix, r))
677     }
678 }
679 
680 impl<B, T> Ref<B, T>
681 where
682     B: ByteSlice,
683     T: KnownLayout<PointerMetadata = usize> + Immutable + ?Sized,
684 {
685     /// Constructs a `Ref` from the given bytes with DST length equal to `count`
686     /// without copying.
687     ///
688     /// This method attempts to return a `Ref` to the prefix of `source`
689     /// interpreted as a `T` with `count` trailing elements, and a reference to
690     /// the remaining bytes. If the length of `source` is not equal to the size
691     /// of `Self` with `count` elements, or if `source` is not appropriately
692     /// aligned, this returns `Err`. If [`T: Unaligned`][t-unaligned], you can
693     /// [infallibly discard the alignment error][size-error-from].
694     ///
695     /// [t-unaligned]: crate::Unaligned
696     /// [size-error-from]: error/struct.SizeError.html#method.from-1
697     ///
698     /// # Compile-Time Assertions
699     ///
700     /// This method cannot yet be used on unsized types whose dynamically-sized
701     /// component is zero-sized. Attempting to use this method on such types
702     /// results in a compile-time assertion error; e.g.:
703     ///
704     /// ```compile_fail,E0080
705     /// use zerocopy::*;
706     /// # use zerocopy_derive::*;
707     ///
708     /// #[derive(Immutable, KnownLayout)]
709     /// #[repr(C)]
710     /// struct ZSTy {
711     ///     leading_sized: u16,
712     ///     trailing_dst: [()],
713     /// }
714     ///
715     /// let _ = Ref::<_, ZSTy>::from_bytes_with_elems(&b"UU"[..], 42); // ⚠ Compile Error!
716     /// ```
717     ///
718     #[doc = codegen_section!(
719         header = "h5",
720         bench = "ref_type_from_bytes_with_elems",
721         format = "coco",
722         arity = 2,
723         [
724             open
725             @index 1
726             @title "Unsized"
727             @variant "dynamic_size"
728         ],
729         [
730             @index 2
731             @title "Dynamically Padded"
732             @variant "dynamic_padding"
733         ]
734     )]
735     #[inline]
736     pub fn from_bytes_with_elems(source: B, count: usize) -> Result<Ref<B, T>, CastError<B, T>> {
737         static_assert_dst_is_not_zst!(T);
738         let expected_len = match T::size_for_metadata(count) {
739             Some(len) => len,
740             None => return Err(SizeError::new(source).into()),
741         };
742         if source.len() != expected_len {
743             return Err(SizeError::new(source).into());
744         }
745         if let Err(e) = Ptr::from_ref(source.deref())
746             .try_cast_into_no_leftover::<T, BecauseImmutable>(Some(count))
747         {
748             return Err(e.with_src(()).with_src(source));
749         }
750         // SAFETY: `size_for_metadata(count)` returned `expected_len`, and the
751         // equality check established that this is `source.len()`. This is the
752         // dynamically-known byte size described by `size_of_val` [1]. By its
753         // safety postcondition, `try_cast_into_no_leftover(Some(count))` only
754         // succeeded after producing a `Ptr<T>` aligned as required for
755         // references [2], with that metadata over the same byte range as
756         // `source.deref()`. `ByteSlice` and its applicable subtraits guarantee
757         // that the stored `source` continues to dereference or convert to that
758         // address and length. These facts establish both preconditions of
759         // `new_unchecked`.
760         //
761         // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of_val.html:
762         //
763         //     Returns the size of the pointed-to value in bytes.
764         //
765         //     ... when `T` has no statically-known size ... `size_of_val` can
766         //     be used to get the dynamically-known size.
767         //
768         // [2] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.align_of_val.html:
769         //
770         //     Returns the ABI-required minimum alignment of the type of the
771         //     value that `val` points to.
772         //
773         //     Every reference to a value of the type `T` must be a multiple of
774         //     this number.
775         Ok(unsafe { Ref::new_unchecked(source, count) })
776     }
777 }
778 
779 impl<B, T> Ref<B, T>
780 where
781     B: SplitByteSlice,
782     T: KnownLayout<PointerMetadata = usize> + Immutable + ?Sized,
783 {
784     /// Constructs a `Ref` from the prefix of the given bytes with DST
785     /// length equal to `count` without copying.
786     ///
787     /// This method attempts to return a `Ref` to the prefix of `source`
788     /// interpreted as a `T` with `count` trailing elements, and a reference to
789     /// the remaining bytes. If there are insufficient bytes, or if `source` is
790     /// not appropriately aligned, this returns `Err`. If [`T:
791     /// Unaligned`][t-unaligned], you can [infallibly discard the alignment
792     /// error][size-error-from].
793     ///
794     /// [t-unaligned]: crate::Unaligned
795     /// [size-error-from]: error/struct.SizeError.html#method.from-1
796     ///
797     /// # Compile-Time Assertions
798     ///
799     /// This method cannot yet be used on unsized types whose dynamically-sized
800     /// component is zero-sized. Attempting to use this method on such types
801     /// results in a compile-time assertion error; e.g.:
802     ///
803     /// ```compile_fail,E0080
804     /// use zerocopy::*;
805     /// # use zerocopy_derive::*;
806     ///
807     /// #[derive(Immutable, KnownLayout)]
808     /// #[repr(C)]
809     /// struct ZSTy {
810     ///     leading_sized: u16,
811     ///     trailing_dst: [()],
812     /// }
813     ///
814     /// let _ = Ref::<_, ZSTy>::from_prefix_with_elems(&b"UU"[..], 42); // ⚠ Compile Error!
815     /// ```
816     ///
817     #[doc = codegen_section!(
818         header = "h5",
819         bench = "ref_type_from_prefix_with_elems",
820         format = "coco",
821         arity = 2,
822         [
823             open
824             @index 1
825             @title "Unsized"
826             @variant "dynamic_size"
827         ],
828         [
829             @index 2
830             @title "Dynamically Padded"
831             @variant "dynamic_padding"
832         ]
833     )]
834     #[inline]
835     pub fn from_prefix_with_elems(
836         source: B,
837         count: usize,
838     ) -> Result<(Ref<B, T>, B), CastError<B, T>> {
839         static_assert_dst_is_not_zst!(T);
840         let expected_len = match T::size_for_metadata(count) {
841             Some(len) => len,
842             None => return Err(SizeError::new(source).into()),
843         };
844         let (prefix, bytes) = source.split_at(expected_len).map_err(SizeError::new)?;
845         Self::from_bytes_with_elems(prefix, count).map(move |l| (l, bytes))
846     }
847 
848     /// Constructs a `Ref` from the suffix of the given bytes with DST length
849     /// equal to `count` without copying.
850     ///
851     /// This method attempts to return a `Ref` to the suffix of `source`
852     /// interpreted as a `T` with `count` trailing elements, and a reference to
853     /// the preceding bytes. If there are insufficient bytes, or if that suffix
854     /// of `source` is not appropriately aligned, this returns `Err`. If [`T:
855     /// Unaligned`][t-unaligned], you can [infallibly discard the alignment
856     /// error][size-error-from].
857     ///
858     /// [t-unaligned]: crate::Unaligned
859     /// [size-error-from]: error/struct.SizeError.html#method.from-1
860     ///
861     /// # Compile-Time Assertions
862     ///
863     /// This method cannot yet be used on unsized types whose dynamically-sized
864     /// component is zero-sized. Attempting to use this method on such types
865     /// results in a compile-time assertion error; e.g.:
866     ///
867     /// ```compile_fail,E0080
868     /// use zerocopy::*;
869     /// # use zerocopy_derive::*;
870     ///
871     /// #[derive(Immutable, KnownLayout)]
872     /// #[repr(C)]
873     /// struct ZSTy {
874     ///     leading_sized: u16,
875     ///     trailing_dst: [()],
876     /// }
877     ///
878     /// let _ = Ref::<_, ZSTy>::from_suffix_with_elems(&b"UU"[..], 42); // ⚠ Compile Error!
879     /// ```
880     ///
881     #[doc = codegen_section!(
882         header = "h5",
883         bench = "ref_type_from_suffix_with_elems",
884         format = "coco",
885         arity = 2,
886         [
887             open
888             @index 1
889             @title "Unsized"
890             @variant "dynamic_size"
891         ],
892         [
893             @index 2
894             @title "Dynamically Padded"
895             @variant "dynamic_padding"
896         ]
897     )]
898     #[inline]
899     pub fn from_suffix_with_elems(
900         source: B,
901         count: usize,
902     ) -> Result<(B, Ref<B, T>), CastError<B, T>> {
903         static_assert_dst_is_not_zst!(T);
904         let expected_len = match T::size_for_metadata(count) {
905             Some(len) => len,
906             None => return Err(SizeError::new(source).into()),
907         };
908         let split_at = if let Some(split_at) = source.len().checked_sub(expected_len) {
909             split_at
910         } else {
911             return Err(SizeError::new(source).into());
912         };
913         // SAFETY: The preceding `source.len().checked_sub(expected_len)`
914         // guarantees that `split_at` is in-bounds.
915         let (bytes, suffix) = unsafe { source.split_at_unchecked(split_at) };
916         Self::from_bytes_with_elems(suffix, count).map(move |l| (bytes, l))
917     }
918 }
919 
920 impl<'a, B, T> Ref<B, T>
921 where
922     B: 'a + IntoByteSlice<'a>,
923     T: FromBytes + KnownLayout + Immutable + ?Sized,
924 {
925     /// Converts this `Ref` into a reference.
926     ///
927     /// `into_ref` consumes the `Ref`, and returns a reference to `T`.
928     ///
929     /// Note: this is an associated function, which means that you have to call
930     /// it as `Ref::into_ref(r)` instead of `r.into_ref()`. This is so that
931     /// there is no conflict with a method on the inner type.
932     ///
933     #[doc = codegen_section!(
934         header = "h5",
935         bench = "ref_type_into_ref",
936         format = "coco",
937         arity = 3,
938         [
939             open
940             @index 1
941             @title "Sized"
942             @variant "static_size"
943         ],
944         [
945             @index 2
946             @title "Unsized"
947             @variant "dynamic_size"
948         ],
949         [
950             @index 3
951             @title "Dynamically Padded"
952             @variant "dynamic_padding"
953         ]
954     )]
955     #[must_use = "has no side effects"]
956     #[inline(always)]
957     pub fn into_ref(r: Self) -> &'a T {
958         // Presumably unreachable, since we've guarded each constructor of `Ref`.
959         static_assert_dst_is_not_zst!(T);
960 
961         let metadata = r.pointer_metadata();
962 
963         // SAFETY: We don't call any methods on `b` other than those provided by
964         // `IntoByteSlice`.
965         let b = unsafe { r.into_byte_slice() };
966         let b = b.into_byte_slice();
967 
968         if let crate::layout::SizeInfo::Sized { .. } = T::LAYOUT.size_info {
969             let ptr = Ptr::from_ref(b);
970             // SAFETY: We just checked that `T: Sized`. By invariant on `r`,
971             // `b`'s size is equal to `size_of::<T>()`.
972             let ptr = unsafe { cast_for_sized::<T, _, _, _>(ptr) };
973 
974             // SAFETY: None of the preceding transformations modifies the
975             // address of the pointer, and by invariant on `r`, we know that it
976             // is validly-aligned.
977             let ptr = unsafe { ptr.assume_alignment::<Aligned>() };
978             return ptr.as_ref();
979         }
980 
981         // PANICS: By post-condition on `into_byte_slice`, `b` is aligned for
982         // `T`, and its size is exactly the size encoded by `metadata`. By
983         // post-condition, `b.into_byte_slice()` produces a byte slice with
984         // identical address and length to that produced by `b.deref()`.
985         let ptr = Ptr::from_ref(b.into_byte_slice())
986             .try_cast_into_no_leftover::<T, BecauseImmutable>(Some(metadata))
987             .expect("zerocopy internal error: into_ref should be infallible");
988         let ptr = ptr.recall_validity();
989         ptr.as_ref()
990     }
991 }
992 
993 impl<'a, B, T> Ref<B, T>
994 where
995     B: 'a + IntoByteSliceMut<'a>,
996     T: FromBytes + IntoBytes + KnownLayout + ?Sized,
997 {
998     /// Converts this `Ref` into a mutable reference.
999     ///
1000     /// `into_mut` consumes the `Ref`, and returns a mutable reference to `T`.
1001     ///
1002     /// Note: this is an associated function, which means that you have to call
1003     /// it as `Ref::into_mut(r)` instead of `r.into_mut()`. This is so that
1004     /// there is no conflict with a method on the inner type.
1005     ///
1006     #[doc = codegen_section!(
1007         header = "h5",
1008         bench = "ref_type_into_mut",
1009         format = "coco",
1010         arity = 2,
1011         [
1012             open
1013             @index 1
1014             @title "Sized"
1015             @variant "static_size"
1016         ],
1017         [
1018             @index 2
1019             @title "Unsized"
1020             @variant "dynamic_size"
1021         ]
1022     )]
1023     #[must_use = "has no side effects"]
1024     #[inline(always)]
1025     pub fn into_mut(r: Self) -> &'a mut T {
1026         // Presumably unreachable, since we've guarded each constructor of `Ref`.
1027         static_assert_dst_is_not_zst!(T);
1028 
1029         let metadata = r.pointer_metadata();
1030 
1031         // SAFETY: We don't call any methods on `b` other than those provided by
1032         // `IntoByteSliceMut`.
1033         let b = unsafe { r.into_byte_slice_mut() };
1034         let b = b.into_byte_slice_mut();
1035 
1036         if let crate::layout::SizeInfo::Sized { .. } = T::LAYOUT.size_info {
1037             let ptr = Ptr::from_mut(b);
1038             // SAFETY: We just checked that `T: Sized`. By invariant on `r`,
1039             // `b`'s size is equal to `size_of::<T>()`.
1040             let ptr = unsafe {
1041                 cast_for_sized::<
1042                     T,
1043                     _,
1044                     (BecauseRead, BecauseExclusive),
1045                     (BecauseMutationCompatible, BecauseSharedCompatible),
1046                 >(ptr)
1047             };
1048 
1049             // SAFETY: None of the preceding transformations modifies the
1050             // address of the pointer, and by invariant on `r`, we know that it
1051             // is validly-aligned.
1052             let ptr = unsafe { ptr.assume_alignment::<Aligned>() };
1053             return ptr.as_mut();
1054         }
1055 
1056         // PANICS: By post-condition on `into_byte_slice_mut`, `b` is aligned
1057         // for `T`, and its size is exactly the size encoded by `metadata`. By
1058         // post-condition, `b.into_byte_slice_mut()` produces a byte slice with
1059         // identical address and length to that produced by `b.deref_mut()`.
1060         let ptr = Ptr::from_mut(b.into_byte_slice_mut())
1061             .try_cast_into_no_leftover::<T, BecauseExclusive>(Some(metadata))
1062             .expect("zerocopy internal error: into_mut should be infallible");
1063         let ptr = ptr.recall_validity::<_, (_, (_, _))>();
1064         ptr.as_mut()
1065     }
1066 }
1067 
1068 impl<B, T> Ref<B, T>
1069 where
1070     B: ByteSlice,
1071     T: ?Sized,
1072 {
1073     /// Gets the underlying bytes.
1074     ///
1075     /// Note: this is an associated function, which means that you have to call
1076     /// it as `Ref::bytes(r)` instead of `r.bytes()`. This is so that there is
1077     /// no conflict with a method on the inner type.
1078     ///
1079     #[doc = codegen_section!(
1080         header = "h5",
1081         bench = "ref_type_bytes",
1082         format = "coco",
1083         arity = 3,
1084         [
1085             open
1086             @index 1
1087             @title "Sized"
1088             @variant "static_size"
1089         ],
1090         [
1091             @index 2
1092             @title "Unsized"
1093             @variant "dynamic_size"
1094         ],
1095         [
1096             @index 3
1097             @title "Dynamically Padded"
1098             @variant "dynamic_padding"
1099         ]
1100     )]
1101     #[inline]
1102     pub fn bytes(r: &Self) -> &[u8] {
1103         // SAFETY: We don't call any methods on `b` other than those provided by
1104         // `ByteSlice`.
1105         unsafe { r.as_byte_slice().deref() }
1106     }
1107 }
1108 
1109 impl<B, T> Ref<B, T>
1110 where
1111     B: ByteSliceMut,
1112     T: ?Sized,
1113 {
1114     /// Gets the underlying bytes mutably.
1115     ///
1116     /// Note: this is an associated function, which means that you have to call
1117     /// it as `Ref::bytes_mut(r)` instead of `r.bytes_mut()`. This is so that
1118     /// there is no conflict with a method on the inner type.
1119     ///
1120     #[doc = codegen_section!(
1121         header = "h5",
1122         bench = "ref_type_bytes_mut",
1123         format = "coco",
1124         arity = 3,
1125         [
1126             open
1127             @index 1
1128             @title "Sized"
1129             @variant "static_size"
1130         ],
1131         [
1132             @index 2
1133             @title "Unsized"
1134             @variant "dynamic_size"
1135         ],
1136         [
1137             @index 3
1138             @title "Dynamically Padded"
1139             @variant "dynamic_padding"
1140         ]
1141     )]
1142     #[inline]
1143     pub fn bytes_mut(r: &mut Self) -> &mut [u8] {
1144         // SAFETY: We don't call any methods on `b` other than those provided by
1145         // `ByteSliceMut`.
1146         unsafe { r.as_byte_slice_mut().deref_mut() }
1147     }
1148 }
1149 
1150 impl<B, T> Ref<B, T>
1151 where
1152     B: ByteSlice,
1153     T: FromBytes,
1154 {
1155     /// Reads a copy of `T`.
1156     ///
1157     /// Note: this is an associated function, which means that you have to call
1158     /// it as `Ref::read(r)` instead of `r.read()`. This is so that there is no
1159     /// conflict with a method on the inner type.
1160     ///
1161     #[doc = codegen_section!(
1162         header = "h5",
1163         bench = "ref_type_read_static_size",
1164         format = "coco_static_size",
1165     )]
1166     #[must_use = "has no side effects"]
1167     #[inline]
1168     pub fn read(r: &Self) -> T {
1169         // SAFETY: We don't call any methods on `b` other than those provided by
1170         // `ByteSlice`.
1171         let b = unsafe { r.as_byte_slice() };
1172 
1173         // SAFETY: By postcondition on `as_byte_slice`, we know that `b` is a
1174         // valid size and alignment for `T`. By safety invariant on `ByteSlice`,
1175         // we know that this is preserved via `.deref()`. Because `T:
1176         // FromBytes`, it is sound to interpret these bytes as a `T`.
1177         unsafe { ptr::read(b.deref().as_ptr().cast::<T>()) }
1178     }
1179 }
1180 
1181 impl<B, T> Ref<B, T>
1182 where
1183     B: ByteSliceMut,
1184     T: IntoBytes,
1185 {
1186     /// Writes the bytes of `t` and then forgets `t`.
1187     ///
1188     /// Note: this is an associated function, which means that you have to call
1189     /// it as `Ref::write(r, t)` instead of `r.write(t)`. This is so that there
1190     /// is no conflict with a method on the inner type.
1191     ///
1192     #[doc = codegen_section!(
1193         header = "h5",
1194         bench = "ref_type_write_static_size",
1195         format = "coco_static_size",
1196     )]
1197     #[inline]
1198     pub fn write(r: &mut Self, t: T) {
1199         // SAFETY: We don't call any methods on `b` other than those provided by
1200         // `ByteSliceMut`.
1201         let b = unsafe { r.as_byte_slice_mut() };
1202 
1203         // SAFETY: By postcondition on `as_byte_slice_mut`, we know that `b` is a
1204         // valid size and alignment for `T`. By safety invariant on
1205         // `ByteSlice`, we know that this is preserved via `.deref()`. Writing
1206         // `t` to the buffer will allow all of the bytes of `t` to be accessed
1207         // as a `[u8]`, but because `T: IntoBytes`, we know that this is sound.
1208         unsafe { ptr::write(b.deref_mut().as_mut_ptr().cast::<T>(), t) }
1209     }
1210 }
1211 
1212 impl<B, T> Deref for Ref<B, T>
1213 where
1214     B: ByteSlice,
1215     T: FromBytes + KnownLayout + Immutable + ?Sized,
1216 {
1217     type Target = T;
1218 
1219     /// Dereferences the value.
1220     ///
1221     #[doc = codegen_section!(
1222         header = "h5",
1223         bench = "ref_type_deref",
1224         format = "coco",
1225         arity = 3,
1226         [
1227             open
1228             @index 1
1229             @title "Sized"
1230             @variant "static_size"
1231         ],
1232         [
1233             @index 2
1234             @title "Unsized"
1235             @variant "dynamic_size"
1236         ],
1237         [
1238             @index 3
1239             @title "Dynamically Padded"
1240             @variant "dynamic_padding"
1241         ]
1242     )]
1243     #[inline]
1244     fn deref(&self) -> &T {
1245         // Presumably unreachable, since we've guarded each constructor of `Ref`.
1246         static_assert_dst_is_not_zst!(T);
1247 
1248         let metadata = self.pointer_metadata();
1249 
1250         // SAFETY: We don't call any methods on `b` other than those provided by
1251         // `ByteSlice`.
1252         let b = unsafe { self.as_byte_slice() };
1253         let b = b.deref();
1254 
1255         if let crate::layout::SizeInfo::Sized { .. } = T::LAYOUT.size_info {
1256             let ptr = Ptr::from_ref(b);
1257             // SAFETY: We just checked that `T: Sized`. By invariant on `r`,
1258             // `b`'s size is equal to `size_of::<T>()`.
1259             let ptr = unsafe { cast_for_sized::<T, _, _, _>(ptr) };
1260 
1261             // SAFETY: None of the preceding transformations modifies the
1262             // address of the pointer, and by invariant on `r`, we know that it
1263             // is validly-aligned.
1264             let ptr = unsafe { ptr.assume_alignment::<Aligned>() };
1265             return ptr.as_ref();
1266         }
1267 
1268         // PANICS: By postcondition on `as_byte_slice`, `b` is aligned for `T`,
1269         // and its size is exactly the size encoded by `metadata`. By invariant
1270         // on `ByteSlice`, these are preserved through `.deref()`, so this
1271         // `unwrap` will not panic.
1272         let ptr = Ptr::from_ref(b)
1273             .try_cast_into_no_leftover::<T, BecauseImmutable>(Some(metadata))
1274             .expect("zerocopy internal error: Deref::deref should be infallible");
1275         let ptr = ptr.recall_validity();
1276         ptr.as_ref()
1277     }
1278 }
1279 
1280 impl<B, T> DerefMut for Ref<B, T>
1281 where
1282     B: ByteSliceMut,
1283     // FIXME(#251): We can't remove `Immutable` here because it's required by
1284     // the impl of `Deref`, which is a super-trait of `DerefMut`. Maybe we can
1285     // add a separate inherent method for this?
1286     T: FromBytes + IntoBytes + KnownLayout + Immutable + ?Sized,
1287 {
1288     /// Mutably dereferences the value.
1289     ///
1290     #[doc = codegen_section!(
1291         header = "h5",
1292         bench = "ref_type_deref_mut",
1293         format = "coco",
1294         arity = 2,
1295         [
1296             open
1297             @index 1
1298             @title "Sized"
1299             @variant "static_size"
1300         ],
1301         [
1302             @index 2
1303             @title "Unsized"
1304             @variant "dynamic_size"
1305         ]
1306     )]
1307     #[inline]
1308     fn deref_mut(&mut self) -> &mut T {
1309         // Presumably unreachable, since we've guarded each constructor of `Ref`.
1310         static_assert_dst_is_not_zst!(T);
1311 
1312         let metadata = self.pointer_metadata();
1313 
1314         // SAFETY: We don't call any methods on `b` other than those provided by
1315         // `ByteSliceMut`.
1316         let b = unsafe { self.as_byte_slice_mut() };
1317         let b = b.deref_mut();
1318 
1319         if let crate::layout::SizeInfo::Sized { .. } = T::LAYOUT.size_info {
1320             let ptr = Ptr::from_mut(b);
1321             // SAFETY: We just checked that `T: Sized`. By invariant on `r`,
1322             // `b`'s size is equal to `size_of::<T>()`.
1323             let ptr = unsafe {
1324                 cast_for_sized::<
1325                     T,
1326                     _,
1327                     (BecauseRead, BecauseExclusive),
1328                     (BecauseMutationCompatible, BecauseSharedCompatible),
1329                 >(ptr)
1330             };
1331 
1332             // SAFETY: None of the preceding transformations modifies the
1333             // address of the pointer, and by invariant on `r`, we know that it
1334             // is validly-aligned.
1335             let ptr = unsafe { ptr.assume_alignment::<Aligned>() };
1336             return ptr.as_mut();
1337         }
1338 
1339         // PANICS: By postcondition on `as_byte_slice_mut`, `b` is aligned for
1340         // `T`, and its size is exactly the size encoded by `metadata`. By
1341         // invariant on `ByteSlice`, these are preserved through `.deref_mut()`,
1342         // so this `unwrap` will not panic.
1343         let ptr = Ptr::from_mut(b)
1344             .try_cast_into_no_leftover::<T, BecauseExclusive>(Some(metadata))
1345             .expect("zerocopy internal error: DerefMut::deref_mut should be infallible");
1346         let ptr = ptr.recall_validity::<_, (_, (_, BecauseExclusive))>();
1347         ptr.as_mut()
1348     }
1349 }
1350 
1351 impl<T, B> Display for Ref<B, T>
1352 where
1353     B: ByteSlice,
1354     T: FromBytes + Display + KnownLayout + Immutable + ?Sized,
1355 {
1356     #[inline]
1357     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1358         let inner: &T = self;
1359         inner.fmt(fmt)
1360     }
1361 }
1362 
1363 impl<T, B> Debug for Ref<B, T>
1364 where
1365     B: ByteSlice,
1366     T: FromBytes + Debug + KnownLayout + Immutable + ?Sized,
1367 {
1368     #[inline]
1369     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
1370         let inner: &T = self;
1371         fmt.debug_tuple("Ref").field(&inner).finish()
1372     }
1373 }
1374 
1375 impl<T, B> Eq for Ref<B, T>
1376 where
1377     B: ByteSlice,
1378     T: FromBytes + Eq + KnownLayout + Immutable + ?Sized,
1379 {
1380 }
1381 
1382 impl<T, B> PartialEq for Ref<B, T>
1383 where
1384     B: ByteSlice,
1385     T: FromBytes + PartialEq + KnownLayout + Immutable + ?Sized,
1386 {
1387     #[inline]
1388     fn eq(&self, other: &Self) -> bool {
1389         self.deref().eq(other.deref())
1390     }
1391 }
1392 
1393 impl<T, B> Ord for Ref<B, T>
1394 where
1395     B: ByteSlice,
1396     T: FromBytes + Ord + KnownLayout + Immutable + ?Sized,
1397 {
1398     #[inline]
1399     fn cmp(&self, other: &Self) -> Ordering {
1400         let inner: &T = self;
1401         let other_inner: &T = other;
1402         inner.cmp(other_inner)
1403     }
1404 }
1405 
1406 impl<T, B> PartialOrd for Ref<B, T>
1407 where
1408     B: ByteSlice,
1409     T: FromBytes + PartialOrd + KnownLayout + Immutable + ?Sized,
1410 {
1411     #[inline]
1412     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1413         let inner: &T = self;
1414         let other_inner: &T = other;
1415         inner.partial_cmp(other_inner)
1416     }
1417 }
1418 
1419 /// # Safety
1420 ///
1421 /// `T: Sized` and `ptr`'s referent must have size `size_of::<T>()`.
1422 #[inline(always)]
1423 unsafe fn cast_for_sized<'a, T, A, R, S>(
1424     ptr: Ptr<'a, [u8], (A, Aligned, Safe)>,
1425 ) -> Ptr<'a, T, (A, Unaligned, Safe)>
1426 where
1427     T: FromBytes + KnownLayout + ?Sized,
1428     A: crate::invariant::Aliasing,
1429     [u8]: MutationCompatible<T, A, Initialized, Initialized, R>,
1430     T: TransmuteFromPtr<T, A, Initialized, Safe, crate::pointer::cast::IdCast, S>,
1431 {
1432     use crate::pointer::cast::{Cast, Project};
1433 
1434     enum CastForSized {}
1435 
1436     // SAFETY: `CastForSized` is only used below with the input `ptr`, which the
1437     // caller promises has size `size_of::<T>()`. Thus, the referent produced in
1438     // this cast has the same size as `ptr`'s referent. All operations preserve
1439     // provenance.
1440     unsafe impl<T: ?Sized + KnownLayout> Project<[u8], T> for CastForSized {
1441         #[inline(always)]
1442         fn project(src: PtrInner<'_, [u8]>) -> *mut T {
1443             T::raw_from_ptr_len(
1444                 src.as_non_null().cast(),
1445                 <T::PointerMetadata as crate::PointerMetadata>::from_elem_count(0),
1446             )
1447             .as_ptr()
1448         }
1449     }
1450 
1451     // SAFETY: The `Project::project` impl preserves referent address.
1452     unsafe impl<T: ?Sized + KnownLayout> Cast<[u8], T> for CastForSized {}
1453 
1454     ptr.recall_validity::<Initialized, (_, (_, _))>()
1455         .cast::<_, CastForSized, _>()
1456         .recall_validity::<Safe, _>()
1457 }
1458 
1459 #[cfg(test)]
1460 #[allow(clippy::assertions_on_result_states)]
1461 mod tests {
1462     use core::convert::TryInto as _;
1463 
1464     use super::*;
1465     use crate::util::testutil::*;
1466 
1467     #[test]
1468     fn test_mut_slice_into_ref() {
1469         // Prior to #1260/#1299, calling `into_ref` on a `&mut [u8]`-backed
1470         // `Ref` was not supported.
1471         let mut buf = [0u8];
1472         let r = Ref::<&mut [u8], u8>::from_bytes(&mut buf).unwrap();
1473         assert_eq!(Ref::into_ref(r), &0);
1474     }
1475 
1476     #[test]
1477     fn test_address() {
1478         // Test that the `Deref` and `DerefMut` implementations return a
1479         // reference which points to the right region of memory.
1480 
1481         let buf = [0];
1482         let r = Ref::<_, u8>::from_bytes(&buf[..]).unwrap();
1483         let buf_ptr = buf.as_ptr();
1484         let deref_ptr: *const u8 = r.deref();
1485         assert_eq!(buf_ptr, deref_ptr);
1486 
1487         let buf = [0];
1488         let r = Ref::<_, [u8]>::from_bytes(&buf[..]).unwrap();
1489         let buf_ptr = buf.as_ptr();
1490         let deref_ptr = r.deref().as_ptr();
1491         assert_eq!(buf_ptr, deref_ptr);
1492     }
1493 
1494     #[test]
1495     #[allow(clippy::clone_on_copy)] // Exercise `Ref`'s manual `Clone` impl.
1496     fn test_with_elems_preserves_ambiguous_metadata() {
1497         #[derive(FromBytes, Immutable, KnownLayout)]
1498         #[repr(C, align(8))]
1499         struct Frame {
1500             header: [u8; 8],
1501             body: [u8],
1502         }
1503 
1504         #[derive(FromBytes, Immutable, KnownLayout)]
1505         #[repr(C, align(8))]
1506         struct OddHeader {
1507             header: [u8; 7],
1508             body: [u8],
1509         }
1510 
1511         // Dynamic trailing padding makes these pairs of distinct element
1512         // counts produce the same total byte size. Thus, the byte length alone
1513         // cannot recover the count supplied to a `*_with_elems` constructor.
1514         assert_eq!(Frame::size_for_metadata(1), Some(16));
1515         assert_eq!(Frame::size_for_metadata(8), Some(16));
1516         assert_eq!(OddHeader::size_for_metadata(0), Some(8));
1517         assert_eq!(OddHeader::size_for_metadata(1), Some(8));
1518 
1519         let bytes = Align::<[u8; 32], AU64>::default();
1520 
1521         let whole = Ref::<_, Frame>::from_bytes_with_elems(&bytes.t[..16], 1).unwrap();
1522         assert_eq!(whole.body.len(), 1);
1523         assert_eq!(Ref::bytes(&whole).len(), 16);
1524         assert_eq!(whole.clone().body.len(), 1);
1525         let copied = whole;
1526         assert_eq!(copied.body.len(), 1);
1527         assert_eq!(Ref::into_ref(whole).body.len(), 1);
1528 
1529         let (prefix, rest) = Ref::<_, Frame>::from_prefix_with_elems(&bytes.t[..], 1).unwrap();
1530         assert_eq!(prefix.body.len(), 1);
1531         assert_eq!(rest.len(), 16);
1532 
1533         let (before, suffix) = Ref::<_, Frame>::from_suffix_with_elems(&bytes.t[..24], 1).unwrap();
1534         assert_eq!(before.len(), 8);
1535         assert_eq!(suffix.body.len(), 1);
1536 
1537         // Zero is real metadata, not a sentinel for "infer from the bytes".
1538         let empty = Ref::<_, OddHeader>::from_bytes_with_elems(&bytes.t[..8], 0).unwrap();
1539         assert!(empty.body.is_empty());
1540         assert!(Ref::into_ref(empty).body.is_empty());
1541 
1542         // The implicit constructors still choose the largest fitting count,
1543         // and retain the metadata selected during their validating cast.
1544         let inferred = Ref::<_, Frame>::from_bytes(&bytes.t[..16]).unwrap();
1545         assert_eq!(inferred.body.len(), 8);
1546         let (inferred, rest) = Ref::<_, Frame>::from_prefix(&bytes.t[..16]).unwrap();
1547         assert_eq!(inferred.body.len(), 8);
1548         assert!(rest.is_empty());
1549         let (before, inferred) = Ref::<_, Frame>::from_suffix(&bytes.t[..16]).unwrap();
1550         assert!(before.is_empty());
1551         assert_eq!(inferred.body.len(), 8);
1552     }
1553 
1554     // Verify that values written to a `Ref` are properly shared between the
1555     // typed and untyped representations, that reads via `deref` and `read`
1556     // behave the same, and that writes via `deref_mut` and `write` behave the
1557     // same.
1558     fn test_new_helper(mut r: Ref<&mut [u8], AU64>) {
1559         // assert that the value starts at 0
1560         assert_eq!(*r, AU64(0));
1561         assert_eq!(Ref::read(&r), AU64(0));
1562 
1563         // Assert that values written to the typed value are reflected in the
1564         // byte slice.
1565         const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
1566         *r = VAL1;
1567         assert_eq!(Ref::bytes(&r), &VAL1.to_bytes());
1568         *r = AU64(0);
1569         Ref::write(&mut r, VAL1);
1570         assert_eq!(Ref::bytes(&r), &VAL1.to_bytes());
1571 
1572         // Assert that values written to the byte slice are reflected in the
1573         // typed value.
1574         const VAL2: AU64 = AU64(!VAL1.0); // different from `VAL1`
1575         Ref::bytes_mut(&mut r).copy_from_slice(&VAL2.to_bytes()[..]);
1576         assert_eq!(*r, VAL2);
1577         assert_eq!(Ref::read(&r), VAL2);
1578     }
1579 
1580     // Verify that values written to a `Ref` are properly shared between the
1581     // typed and untyped representations; pass a value with `typed_len` `AU64`s
1582     // backed by an array of `typed_len * 8` bytes.
1583     fn test_new_helper_slice(mut r: Ref<&mut [u8], [AU64]>, typed_len: usize) {
1584         // Assert that the value starts out zeroed.
1585         assert_eq!(&*r, vec![AU64(0); typed_len].as_slice());
1586 
1587         // Check the backing storage is the exact same slice.
1588         let untyped_len = typed_len * 8;
1589         assert_eq!(Ref::bytes(&r).len(), untyped_len);
1590         assert_eq!(Ref::bytes(&r).as_ptr(), r.as_ptr().cast::<u8>());
1591 
1592         // Assert that values written to the typed value are reflected in the
1593         // byte slice.
1594         const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
1595         for typed in &mut *r {
1596             *typed = VAL1;
1597         }
1598         assert_eq!(Ref::bytes(&r), VAL1.0.to_ne_bytes().repeat(typed_len).as_slice());
1599 
1600         // Assert that values written to the byte slice are reflected in the
1601         // typed value.
1602         const VAL2: AU64 = AU64(!VAL1.0); // different from VAL1
1603         Ref::bytes_mut(&mut r).copy_from_slice(&VAL2.0.to_ne_bytes().repeat(typed_len));
1604         assert!(r.iter().copied().all(|x| x == VAL2));
1605     }
1606 
1607     #[test]
1608     fn test_new_aligned_sized() {
1609         // Test that a properly-aligned, properly-sized buffer works for new,
1610         // new_from_prefix, and new_from_suffix, and that new_from_prefix and
1611         // new_from_suffix return empty slices. Test that a properly-aligned
1612         // buffer whose length is a multiple of the element size works for
1613         // new_slice.
1614 
1615         // A buffer with an alignment of 8.
1616         let mut buf = Align::<[u8; 8], AU64>::default();
1617         // `buf.t` should be aligned to 8, so this should always succeed.
1618         test_new_helper(Ref::<_, AU64>::from_bytes(&mut buf.t[..]).unwrap());
1619         {
1620             // In a block so that `r` and `suffix` don't live too long.
1621             buf.set_default();
1622             let (r, suffix) = Ref::<_, AU64>::from_prefix(&mut buf.t[..]).unwrap();
1623             assert!(suffix.is_empty());
1624             test_new_helper(r);
1625         }
1626         {
1627             buf.set_default();
1628             let (prefix, r) = Ref::<_, AU64>::from_suffix(&mut buf.t[..]).unwrap();
1629             assert!(prefix.is_empty());
1630             test_new_helper(r);
1631         }
1632 
1633         // A buffer with alignment 8 and length 24. We choose this length very
1634         // intentionally: if we instead used length 16, then the prefix and
1635         // suffix lengths would be identical. In the past, we used length 16,
1636         // which resulted in this test failing to discover the bug uncovered in
1637         // #506.
1638         let mut buf = Align::<[u8; 24], AU64>::default();
1639         // `buf.t` should be aligned to 8 and have a length which is a multiple
1640         // of `size_of::<AU64>()`, so this should always succeed.
1641         test_new_helper_slice(Ref::<_, [AU64]>::from_bytes(&mut buf.t[..]).unwrap(), 3);
1642         buf.set_default();
1643         let r = Ref::<_, [AU64]>::from_bytes_with_elems(&mut buf.t[..], 3).unwrap();
1644         test_new_helper_slice(r, 3);
1645 
1646         let ascending: [u8; 24] = (0..24).collect::<Vec<_>>().try_into().unwrap();
1647         // 16 ascending bytes followed by 8 zeros.
1648         let mut ascending_prefix = ascending;
1649         ascending_prefix[16..].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
1650         // 8 zeros followed by 16 ascending bytes.
1651         let mut ascending_suffix = ascending;
1652         ascending_suffix[..8].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
1653         {
1654             buf.t = ascending_suffix;
1655             let (r, suffix) = Ref::<_, [AU64]>::from_prefix_with_elems(&mut buf.t[..], 1).unwrap();
1656             assert_eq!(suffix, &ascending[8..]);
1657             test_new_helper_slice(r, 1);
1658         }
1659         {
1660             buf.t = ascending_prefix;
1661             let (prefix, r) = Ref::<_, [AU64]>::from_suffix_with_elems(&mut buf.t[..], 1).unwrap();
1662             assert_eq!(prefix, &ascending[..16]);
1663             test_new_helper_slice(r, 1);
1664         }
1665     }
1666 
1667     #[test]
1668     fn test_new_oversized() {
1669         // Test that a properly-aligned, overly-sized buffer works for
1670         // `new_from_prefix` and `new_from_suffix`, and that they return the
1671         // remainder and prefix of the slice respectively.
1672 
1673         let mut buf = Align::<[u8; 16], AU64>::default();
1674         {
1675             // In a block so that `r` and `suffix` don't live too long. `buf.t`
1676             // should be aligned to 8, so this should always succeed.
1677             let (r, suffix) = Ref::<_, AU64>::from_prefix(&mut buf.t[..]).unwrap();
1678             assert_eq!(suffix.len(), 8);
1679             test_new_helper(r);
1680         }
1681         {
1682             buf.set_default();
1683             // `buf.t` should be aligned to 8, so this should always succeed.
1684             let (prefix, r) = Ref::<_, AU64>::from_suffix(&mut buf.t[..]).unwrap();
1685             assert_eq!(prefix.len(), 8);
1686             test_new_helper(r);
1687         }
1688     }
1689 
1690     #[test]
1691     #[allow(clippy::cognitive_complexity)]
1692     fn test_new_error() {
1693         // Fail because the buffer is too large.
1694 
1695         // A buffer with an alignment of 8.
1696         let buf = Align::<[u8; 16], AU64>::default();
1697         // `buf.t` should be aligned to 8, so only the length check should fail.
1698         assert!(Ref::<_, AU64>::from_bytes(&buf.t[..]).is_err());
1699 
1700         // Fail because the buffer is too small.
1701 
1702         // A buffer with an alignment of 8.
1703         let buf = Align::<[u8; 4], AU64>::default();
1704         // `buf.t` should be aligned to 8, so only the length check should fail.
1705         assert!(Ref::<_, AU64>::from_bytes(&buf.t[..]).is_err());
1706         assert!(Ref::<_, AU64>::from_prefix(&buf.t[..]).is_err());
1707         assert!(Ref::<_, AU64>::from_suffix(&buf.t[..]).is_err());
1708 
1709         // Fail because the length is not a multiple of the element size.
1710 
1711         let buf = Align::<[u8; 12], AU64>::default();
1712         // `buf.t` has length 12, but element size is 8.
1713         assert!(Ref::<_, [AU64]>::from_bytes(&buf.t[..]).is_err());
1714 
1715         // Fail because the buffer is too short.
1716         let buf = Align::<[u8; 12], AU64>::default();
1717         // `buf.t` has length 12, but the element size is 8 (and we're expecting
1718         // two of them). For each function, we test with a length that would
1719         // cause the size to overflow `usize`, and with a normal length that
1720         // will fail thanks to the buffer being too short; these are different
1721         // error paths, and while the error types are the same, the distinction
1722         // shows up in code coverage metrics.
1723         let n = (usize::MAX / mem::size_of::<AU64>()) + 1;
1724         assert!(Ref::<_, [AU64]>::from_bytes_with_elems(&buf.t[..], n).is_err());
1725         assert!(Ref::<_, [AU64]>::from_bytes_with_elems(&buf.t[..], 2).is_err());
1726         assert!(Ref::<_, [AU64]>::from_prefix_with_elems(&buf.t[..], n).is_err());
1727         assert!(Ref::<_, [AU64]>::from_prefix_with_elems(&buf.t[..], 2).is_err());
1728         assert!(Ref::<_, [AU64]>::from_suffix_with_elems(&buf.t[..], n).is_err());
1729         assert!(Ref::<_, [AU64]>::from_suffix_with_elems(&buf.t[..], 2).is_err());
1730 
1731         // Fail because the alignment is insufficient.
1732 
1733         // A buffer with an alignment of 8. An odd buffer size is chosen so that
1734         // the last byte of the buffer has odd alignment.
1735         let buf = Align::<[u8; 13], AU64>::default();
1736         // Slicing from 1, we get a buffer with size 12 (so the length check
1737         // should succeed) but an alignment of only 1, which is insufficient.
1738         assert!(Ref::<_, AU64>::from_bytes(&buf.t[1..]).is_err());
1739         assert!(Ref::<_, AU64>::from_prefix(&buf.t[1..]).is_err());
1740         assert!(Ref::<_, [AU64]>::from_bytes(&buf.t[1..]).is_err());
1741         assert!(Ref::<_, [AU64]>::from_bytes_with_elems(&buf.t[1..], 1).is_err());
1742         assert!(Ref::<_, [AU64]>::from_prefix_with_elems(&buf.t[1..], 1).is_err());
1743         assert!(Ref::<_, [AU64]>::from_suffix_with_elems(&buf.t[1..], 1).is_err());
1744         // Slicing is unnecessary here because `new_from_suffix` uses the suffix
1745         // of the slice, which has odd alignment.
1746         assert!(Ref::<_, AU64>::from_suffix(&buf.t[..]).is_err());
1747 
1748         // Fail due to arithmetic overflow.
1749 
1750         let buf = Align::<[u8; 16], AU64>::default();
1751         let unreasonable_len = usize::MAX / mem::size_of::<AU64>() + 1;
1752         assert!(Ref::<_, [AU64]>::from_prefix_with_elems(&buf.t[..], unreasonable_len).is_err());
1753         assert!(Ref::<_, [AU64]>::from_suffix_with_elems(&buf.t[..], unreasonable_len).is_err());
1754     }
1755 
1756     #[test]
1757     #[allow(unstable_name_collisions)]
1758     #[allow(clippy::as_conversions)]
1759     fn test_into_ref_mut() {
1760         #[allow(unused)]
1761         use crate::util::AsAddress as _;
1762 
1763         let mut buf = Align::<[u8; 8], u64>::default();
1764         let r = Ref::<_, u64>::from_bytes(&buf.t[..]).unwrap();
1765         let rf = Ref::into_ref(r);
1766         assert_eq!(rf, &0u64);
1767         let buf_addr = (&buf.t as *const [u8; 8]).addr();
1768         assert_eq!((rf as *const u64).addr(), buf_addr);
1769 
1770         let r = Ref::<_, u64>::from_bytes(&mut buf.t[..]).unwrap();
1771         let rf = Ref::into_mut(r);
1772         assert_eq!(rf, &mut 0u64);
1773         assert_eq!((rf as *mut u64).addr(), buf_addr);
1774 
1775         *rf = u64::MAX;
1776         assert_eq!(buf.t, [0xFF; 8]);
1777 
1778         // Exercise the unsized `into_mut` route, which must use the metadata
1779         // retained by the constructor rather than infer fresh metadata.
1780         let mut buf = Align::<[u8; 8], u16>::default();
1781         let r = Ref::<_, [u16]>::from_bytes_with_elems(&mut buf.t[..], 4).unwrap();
1782         let rf = Ref::into_mut(r);
1783         assert_eq!(rf.len(), 4);
1784     }
1785 
1786     #[test]
1787     fn test_display_debug() {
1788         let buf = Align::<[u8; 8], u64>::default();
1789         let r = Ref::<_, u64>::from_bytes(&buf.t[..]).unwrap();
1790         assert_eq!(format!("{}", r), "0");
1791         assert_eq!(format!("{:?}", r), "Ref(0)");
1792 
1793         let buf = Align::<[u8; 8], u64>::default();
1794         let r = Ref::<_, [u64]>::from_bytes(&buf.t[..]).unwrap();
1795         assert_eq!(format!("{:?}", r), "Ref([0])");
1796     }
1797 
1798     #[test]
1799     fn test_eq() {
1800         let buf1 = 0_u64;
1801         let r1 = Ref::<_, u64>::from_bytes(buf1.as_bytes()).unwrap();
1802         let buf2 = 0_u64;
1803         let r2 = Ref::<_, u64>::from_bytes(buf2.as_bytes()).unwrap();
1804         assert_eq!(r1, r2);
1805     }
1806 
1807     #[test]
1808     fn test_ne() {
1809         let buf1 = 0_u64;
1810         let r1 = Ref::<_, u64>::from_bytes(buf1.as_bytes()).unwrap();
1811         let buf2 = 1_u64;
1812         let r2 = Ref::<_, u64>::from_bytes(buf2.as_bytes()).unwrap();
1813         assert_ne!(r1, r2);
1814     }
1815 
1816     #[test]
1817     fn test_ord() {
1818         let buf1 = 0_u64;
1819         let r1 = Ref::<_, u64>::from_bytes(buf1.as_bytes()).unwrap();
1820         let buf2 = 1_u64;
1821         let r2 = Ref::<_, u64>::from_bytes(buf2.as_bytes()).unwrap();
1822         assert!(r1 < r2);
1823         assert_eq!(PartialOrd::partial_cmp(&r1, &r2), Some(Ordering::Less));
1824         assert_eq!(Ord::cmp(&r1, &r2), Ordering::Less);
1825     }
1826 }
1827 
1828 #[cfg(all(test, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS))]
1829 mod benches {
1830     use test::{self, Bencher};
1831 
1832     use super::*;
1833     use crate::util::testutil::*;
1834 
1835     #[bench]
1836     fn bench_from_bytes_sized(b: &mut Bencher) {
1837         let buf = Align::<[u8; 8], AU64>::default();
1838         // `buf.t` should be aligned to 8, so this should always succeed.
1839         let bytes = &buf.t[..];
1840         b.iter(|| test::black_box(Ref::<_, AU64>::from_bytes(test::black_box(bytes)).unwrap()));
1841     }
1842 
1843     #[bench]
1844     fn bench_into_ref_sized(b: &mut Bencher) {
1845         let buf = Align::<[u8; 8], AU64>::default();
1846         let bytes = &buf.t[..];
1847         let r = Ref::<_, AU64>::from_bytes(bytes).unwrap();
1848         b.iter(|| test::black_box(Ref::into_ref(test::black_box(r))));
1849     }
1850 
1851     #[bench]
1852     fn bench_into_mut_sized(b: &mut Bencher) {
1853         let mut buf = Align::<[u8; 8], AU64>::default();
1854         let buf = &mut buf.t[..];
1855         let _ = Ref::<_, AU64>::from_bytes(&mut *buf).unwrap();
1856         b.iter(move || {
1857             // SAFETY: The preceding `from_bytes` succeeded, and so we know that
1858             // `buf` is validly aligned and has the `size_of::<AU64>()` byte
1859             // length required by `new_sized_unchecked` [1].
1860             //
1861             // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of.html:
1862             //
1863             //     Returns the size of a type in bytes.
1864             let r = unsafe { Ref::<&mut [u8], AU64>::new_sized_unchecked(&mut *buf) };
1865             test::black_box(Ref::into_mut(test::black_box(r)));
1866         });
1867     }
1868 
1869     #[bench]
1870     fn bench_deref_sized(b: &mut Bencher) {
1871         let buf = Align::<[u8; 8], AU64>::default();
1872         let bytes = &buf.t[..];
1873         let r = Ref::<_, AU64>::from_bytes(bytes).unwrap();
1874         b.iter(|| {
1875             let temp = test::black_box(r);
1876             test::black_box(temp.deref());
1877         });
1878     }
1879 
1880     #[bench]
1881     fn bench_deref_mut_sized(b: &mut Bencher) {
1882         let mut buf = Align::<[u8; 8], AU64>::default();
1883         let buf = &mut buf.t[..];
1884         let _ = Ref::<_, AU64>::from_bytes(&mut *buf).unwrap();
1885         b.iter(|| {
1886             // SAFETY: The preceding `from_bytes` succeeded, and so we know that
1887             // `buf` is validly aligned and has the `size_of::<AU64>()` byte
1888             // length required by `new_sized_unchecked` [1].
1889             //
1890             // [1] Per https://doc.rust-lang.org/1.56.0/core/mem/fn.size_of.html:
1891             //
1892             //     Returns the size of a type in bytes.
1893             let r = unsafe { Ref::<&mut [u8], AU64>::new_sized_unchecked(&mut *buf) };
1894             let mut temp = test::black_box(r);
1895             test::black_box(temp.deref_mut());
1896         });
1897     }
1898 }
1899