zerocopy/
lib.rs

1// Copyright 2018 The Fuchsia Authors
2//
3// Licensed under the 2-Clause BSD License <LICENSE-BSD or
4// https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0
5// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
6// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
7// This file may not be copied, modified, or distributed except according to
8// those terms.
9
10// After updating the following doc comment, make sure to run the following
11// command to update `README.md` based on its contents:
12//
13//   ./generate-readme.sh > README.md
14
15//! *<span style="font-size: 100%; color:grey;">Want to help improve zerocopy?
16//! Fill out our [user survey][user-survey]!</span>*
17//!
18//! ***<span style="font-size: 140%">Fast, safe, <span
19//! style="color:red;">compile error</span>. Pick two.</span>***
20//!
21//! Zerocopy makes zero-cost memory manipulation effortless. We write `unsafe`
22//! so you don't have to.
23//!
24//! # Overview
25//!
26//! Zerocopy provides four core marker traits, each of which can be derived
27//! (e.g., `#[derive(FromZeroes)]`):
28//! - [`FromZeroes`] indicates that a sequence of zero bytes represents a valid
29//!   instance of a type
30//! - [`FromBytes`] indicates that a type may safely be converted from an
31//!   arbitrary byte sequence
32//! - [`AsBytes`] indicates that a type may safely be converted *to* a byte
33//!   sequence
34//! - [`Unaligned`] indicates that a type's alignment requirement is 1
35//!
36//! Types which implement a subset of these traits can then be converted to/from
37//! byte sequences with little to no runtime overhead.
38//!
39//! Zerocopy also provides byte-order aware integer types that support these
40//! conversions; see the [`byteorder`] module. These types are especially useful
41//! for network parsing.
42//!
43//! [user-survey]: https://docs.google.com/forms/d/e/1FAIpQLSdzBNTN9tzwsmtyZxRFNL02K36IWCdHWW2ZBckyQS2xiO3i8Q/viewform?usp=published_options
44//!
45//! # Cargo Features
46//!
47//! - **`alloc`**   
48//!   By default, `zerocopy` is `no_std`. When the `alloc` feature is enabled,
49//!   the `alloc` crate is added as a dependency, and some allocation-related
50//!   functionality is added.
51//!
52//! - **`byteorder`** (enabled by default)   
53//!   Adds the [`byteorder`] module and a dependency on the `byteorder` crate.
54//!   The `byteorder` module provides byte order-aware equivalents of the
55//!   multi-byte primitive numerical types. Unlike their primitive equivalents,
56//!   the types in this module have no alignment requirement and support byte
57//!   order conversions. This can be useful in handling file formats, network
58//!   packet layouts, etc which don't provide alignment guarantees and which may
59//!   use a byte order different from that of the execution platform.
60//!
61//! - **`derive`**   
62//!   Provides derives for the core marker traits via the `zerocopy-derive`
63//!   crate. These derives are re-exported from `zerocopy`, so it is not
64//!   necessary to depend on `zerocopy-derive` directly.   
65//!
66//!   However, you may experience better compile times if you instead directly
67//!   depend on both `zerocopy` and `zerocopy-derive` in your `Cargo.toml`,
68//!   since doing so will allow Rust to compile these crates in parallel. To do
69//!   so, do *not* enable the `derive` feature, and list both dependencies in
70//!   your `Cargo.toml` with the same leading non-zero version number; e.g:
71//!
72//!   ```toml
73//!   [dependencies]
74//!   zerocopy = "0.X"
75//!   zerocopy-derive = "0.X"
76//!   ```
77//!
78//! - **`simd`**   
79//!   When the `simd` feature is enabled, `FromZeroes`, `FromBytes`, and
80//!   `AsBytes` impls are emitted for all stable SIMD types which exist on the
81//!   target platform. Note that the layout of SIMD types is not yet stabilized,
82//!   so these impls may be removed in the future if layout changes make them
83//!   invalid. For more information, see the Unsafe Code Guidelines Reference
84//!   page on the [layout of packed SIMD vectors][simd-layout].
85//!
86//! - **`simd-nightly`**   
87//!   Enables the `simd` feature and adds support for SIMD types which are only
88//!   available on nightly. Since these types are unstable, support for any type
89//!   may be removed at any point in the future.
90//!
91//! [simd-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
92//!
93//! # Security Ethos
94//!
95//! Zerocopy is expressly designed for use in security-critical contexts. We
96//! strive to ensure that that zerocopy code is sound under Rust's current
97//! memory model, and *any future memory model*. We ensure this by:
98//! - **...not 'guessing' about Rust's semantics.**   
99//!   We annotate `unsafe` code with a precise rationale for its soundness that
100//!   cites a relevant section of Rust's official documentation. When Rust's
101//!   documented semantics are unclear, we work with the Rust Operational
102//!   Semantics Team to clarify Rust's documentation.
103//! - **...rigorously testing our implementation.**   
104//!   We run tests using [Miri], ensuring that zerocopy is sound across a wide
105//!   array of supported target platforms of varying endianness and pointer
106//!   width, and across both current and experimental memory models of Rust.
107//! - **...formally proving the correctness of our implementation.**   
108//!   We apply formal verification tools like [Kani][kani] to prove zerocopy's
109//!   correctness.
110//!
111//! For more information, see our full [soundness policy].
112//!
113//! [Miri]: https://github.com/rust-lang/miri
114//! [Kani]: https://github.com/model-checking/kani
115//! [soundness policy]: https://github.com/google/zerocopy/blob/main/POLICIES.md#soundness
116//!
117//! # Relationship to Project Safe Transmute
118//!
119//! [Project Safe Transmute] is an official initiative of the Rust Project to
120//! develop language-level support for safer transmutation. The Project consults
121//! with crates like zerocopy to identify aspects of safer transmutation that
122//! would benefit from compiler support, and has developed an [experimental,
123//! compiler-supported analysis][mcp-transmutability] which determines whether,
124//! for a given type, any value of that type may be soundly transmuted into
125//! another type. Once this functionality is sufficiently mature, zerocopy
126//! intends to replace its internal transmutability analysis (implemented by our
127//! custom derives) with the compiler-supported one. This change will likely be
128//! an implementation detail that is invisible to zerocopy's users.
129//!
130//! Project Safe Transmute will not replace the need for most of zerocopy's
131//! higher-level abstractions. The experimental compiler analysis is a tool for
132//! checking the soundness of `unsafe` code, not a tool to avoid writing
133//! `unsafe` code altogether. For the foreseeable future, crates like zerocopy
134//! will still be required in order to provide higher-level abstractions on top
135//! of the building block provided by Project Safe Transmute.
136//!
137//! [Project Safe Transmute]: https://rust-lang.github.io/rfcs/2835-project-safe-transmute.html
138//! [mcp-transmutability]: https://github.com/rust-lang/compiler-team/issues/411
139//!
140//! # MSRV
141//!
142//! See our [MSRV policy].
143//!
144//! [MSRV policy]: https://github.com/google/zerocopy/blob/main/POLICIES.md#msrv
145//!
146//! # Changelog
147//!
148//! Zerocopy uses [GitHub Releases].
149//!
150//! [GitHub Releases]: https://github.com/google/zerocopy/releases
151
152// Sometimes we want to use lints which were added after our MSRV.
153// `unknown_lints` is `warn` by default and we deny warnings in CI, so without
154// this attribute, any unknown lint would cause a CI failure when testing with
155// our MSRV.
156//
157// TODO(#1201): Remove `unexpected_cfgs`
158#![allow(unknown_lints, non_local_definitions, unexpected_cfgs)]
159#![deny(renamed_and_removed_lints)]
160#![deny(
161    anonymous_parameters,
162    deprecated_in_future,
163    late_bound_lifetime_arguments,
164    missing_copy_implementations,
165    missing_debug_implementations,
166    missing_docs,
167    path_statements,
168    patterns_in_fns_without_body,
169    rust_2018_idioms,
170    trivial_numeric_casts,
171    unreachable_pub,
172    unsafe_op_in_unsafe_fn,
173    unused_extern_crates,
174    // We intentionally choose not to deny `unused_qualifications`. When items
175    // are added to the prelude (e.g., `core::mem::size_of`), this has the
176    // consequence of making some uses trigger this lint on the latest toolchain
177    // (e.g., `mem::size_of`), but fixing it (e.g. by replacing with `size_of`)
178    // does not work on older toolchains.
179    //
180    // We tested a more complicated fix in #1413, but ultimately decided that,
181    // since this lint is just a minor style lint, the complexity isn't worth it
182    // - it's fine to occasionally have unused qualifications slip through,
183    // especially since these do not affect our user-facing API in any way.
184    variant_size_differences
185)]
186#![cfg_attr(
187    __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
188    deny(fuzzy_provenance_casts, lossy_provenance_casts)
189)]
190#![deny(
191    clippy::all,
192    clippy::alloc_instead_of_core,
193    clippy::arithmetic_side_effects,
194    clippy::as_underscore,
195    clippy::assertions_on_result_states,
196    clippy::as_conversions,
197    clippy::correctness,
198    clippy::dbg_macro,
199    clippy::decimal_literal_representation,
200    clippy::get_unwrap,
201    clippy::indexing_slicing,
202    clippy::missing_inline_in_public_items,
203    clippy::missing_safety_doc,
204    clippy::obfuscated_if_else,
205    clippy::perf,
206    clippy::print_stdout,
207    clippy::std_instead_of_core,
208    clippy::style,
209    clippy::suspicious,
210    clippy::todo,
211    clippy::undocumented_unsafe_blocks,
212    clippy::unimplemented,
213    clippy::unnested_or_patterns,
214    clippy::unwrap_used,
215    clippy::use_debug
216)]
217#![deny(
218    rustdoc::bare_urls,
219    rustdoc::broken_intra_doc_links,
220    rustdoc::invalid_codeblock_attributes,
221    rustdoc::invalid_html_tags,
222    rustdoc::invalid_rust_codeblocks,
223    rustdoc::missing_crate_level_docs,
224    rustdoc::private_intra_doc_links
225)]
226// In test code, it makes sense to weight more heavily towards concise, readable
227// code over correct or debuggable code.
228#![cfg_attr(any(test, kani), allow(
229    // In tests, you get line numbers and have access to source code, so panic
230    // messages are less important. You also often unwrap a lot, which would
231    // make expect'ing instead very verbose.
232    clippy::unwrap_used,
233    // In tests, there's no harm to "panic risks" - the worst that can happen is
234    // that your test will fail, and you'll fix it. By contrast, panic risks in
235    // production code introduce the possibly of code panicking unexpectedly "in
236    // the field".
237    clippy::arithmetic_side_effects,
238    clippy::indexing_slicing,
239))]
240#![cfg_attr(not(test), no_std)]
241#![cfg_attr(
242    all(feature = "simd-nightly", any(target_arch = "x86", target_arch = "x86_64")),
243    feature(stdarch_x86_avx512)
244)]
245#![cfg_attr(
246    all(feature = "simd-nightly", target_arch = "arm"),
247    feature(stdarch_arm_dsp, stdarch_arm_neon_intrinsics)
248)]
249#![cfg_attr(
250    all(feature = "simd-nightly", any(target_arch = "powerpc", target_arch = "powerpc64")),
251    feature(stdarch_powerpc)
252)]
253#![cfg_attr(doc_cfg, feature(doc_cfg))]
254#![cfg_attr(
255    __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
256    feature(layout_for_ptr, strict_provenance)
257)]
258
259// This is a hack to allow zerocopy-derive derives to work in this crate. They
260// assume that zerocopy is linked as an extern crate, so they access items from
261// it as `zerocopy::Xxx`. This makes that still work.
262#[cfg(any(feature = "derive", test))]
263extern crate self as zerocopy;
264
265#[macro_use]
266mod macros;
267
268#[cfg(feature = "byteorder")]
269#[cfg_attr(doc_cfg, doc(cfg(feature = "byteorder")))]
270pub mod byteorder;
271#[doc(hidden)]
272pub mod macro_util;
273mod post_monomorphization_compile_fail_tests;
274mod util;
275// TODO(#252): If we make this pub, come up with a better name.
276mod wrappers;
277
278#[cfg(feature = "byteorder")]
279#[cfg_attr(doc_cfg, doc(cfg(feature = "byteorder")))]
280pub use crate::byteorder::*;
281pub use crate::wrappers::*;
282
283#[cfg(any(feature = "derive", test))]
284#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
285pub use zerocopy_derive::Unaligned;
286
287// `pub use` separately here so that we can mark it `#[doc(hidden)]`.
288//
289// TODO(#29): Remove this or add a doc comment.
290#[cfg(any(feature = "derive", test))]
291#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
292#[doc(hidden)]
293pub use zerocopy_derive::KnownLayout;
294
295use core::{
296    cell::{self, RefMut},
297    cmp::Ordering,
298    fmt::{self, Debug, Display, Formatter},
299    hash::Hasher,
300    marker::PhantomData,
301    mem::{self, ManuallyDrop, MaybeUninit},
302    num::{
303        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
304        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
305    },
306    ops::{Deref, DerefMut},
307    ptr::{self, NonNull},
308    slice,
309};
310
311#[cfg(feature = "alloc")]
312extern crate alloc;
313#[cfg(feature = "alloc")]
314use alloc::{boxed::Box, vec::Vec};
315
316#[cfg(any(feature = "alloc", kani))]
317use core::alloc::Layout;
318
319// Used by `TryFromBytes::is_bit_valid`.
320#[doc(hidden)]
321pub use crate::util::ptr::Ptr;
322
323// For each polyfill, as soon as the corresponding feature is stable, the
324// polyfill import will be unused because method/function resolution will prefer
325// the inherent method/function over a trait method/function. Thus, we suppress
326// the `unused_imports` warning.
327//
328// See the documentation on `util::polyfills` for more information.
329#[allow(unused_imports)]
330use crate::util::polyfills::NonNullExt as _;
331
332#[rustversion::nightly]
333#[cfg(all(test, not(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)))]
334const _: () = {
335    #[deprecated = "some tests may be skipped due to missing RUSTFLAGS=\"--cfg __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS\""]
336    const _WARNING: () = ();
337    #[warn(deprecated)]
338    _WARNING
339};
340
341/// The target pointer width, counted in bits.
342const POINTER_WIDTH_BITS: usize = mem::size_of::<usize>() * 8;
343
344/// The layout of a type which might be dynamically-sized.
345///
346/// `DstLayout` describes the layout of sized types, slice types, and "slice
347/// DSTs" - ie, those that are known by the type system to have a trailing slice
348/// (as distinguished from `dyn Trait` types - such types *might* have a
349/// trailing slice type, but the type system isn't aware of it).
350///
351/// # Safety
352///
353/// Unlike [`core::alloc::Layout`], `DstLayout` is only used to describe full
354/// Rust types - ie, those that satisfy the layout requirements outlined by
355/// [the reference]. Callers may assume that an instance of `DstLayout`
356/// satisfies any conditions imposed on Rust types by the reference.
357///
358/// If `layout: DstLayout` describes a type, `T`, then it is guaranteed that:
359/// - `layout.align` is equal to `T`'s alignment
360/// - If `layout.size_info` is `SizeInfo::Sized { size }`, then `T: Sized` and
361///   `size_of::<T>() == size`
362/// - If `layout.size_info` is `SizeInfo::SliceDst(slice_layout)`, then
363///   - `T` is a slice DST
364/// - The `size` of an instance of `T` with `elems` trailing slice elements is
365///   equal to `slice_layout.offset + slice_layout.elem_size * elems` rounded up
366///   to the nearest multiple of `layout.align`. Any bytes in the range
367///   `[slice_layout.offset + slice_layout.elem_size * elems, size)` are padding
368///   and must not be assumed to be initialized.
369///
370/// [the reference]: https://doc.rust-lang.org/reference/type-layout.html
371#[doc(hidden)]
372#[allow(missing_debug_implementations, missing_copy_implementations)]
373#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
374pub struct DstLayout {
375    align: NonZeroUsize,
376    size_info: SizeInfo,
377}
378
379#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
380enum SizeInfo<E = usize> {
381    Sized { _size: usize },
382    SliceDst(TrailingSliceLayout<E>),
383}
384
385#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
386struct TrailingSliceLayout<E = usize> {
387    // The offset of the first byte of the trailing slice field. Note that this
388    // is NOT the same as the minimum size of the type. For example, consider
389    // the following type:
390    //
391    //   struct Foo {
392    //       a: u16,
393    //       b: u8,
394    //       c: [u8],
395    //   }
396    //
397    // In `Foo`, `c` is at byte offset 3. When `c.len() == 0`, `c` is followed
398    // by a padding byte.
399    _offset: usize,
400    // The size of the element type of the trailing slice field.
401    _elem_size: E,
402}
403
404impl SizeInfo {
405    /// Attempts to create a `SizeInfo` from `Self` in which `elem_size` is a
406    /// `NonZeroUsize`. If `elem_size` is 0, returns `None`.
407    #[allow(unused)]
408    const fn try_to_nonzero_elem_size(&self) -> Option<SizeInfo<NonZeroUsize>> {
409        Some(match *self {
410            SizeInfo::Sized { _size } => SizeInfo::Sized { _size },
411            SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size }) => {
412                if let Some(_elem_size) = NonZeroUsize::new(_elem_size) {
413                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size })
414                } else {
415                    return None;
416                }
417            }
418        })
419    }
420}
421
422#[doc(hidden)]
423#[derive(Copy, Clone)]
424#[cfg_attr(test, derive(Debug))]
425#[allow(missing_debug_implementations)]
426pub enum _CastType {
427    _Prefix,
428    _Suffix,
429}
430
431impl DstLayout {
432    /// The minimum possible alignment of a type.
433    const MIN_ALIGN: NonZeroUsize = match NonZeroUsize::new(1) {
434        Some(min_align) => min_align,
435        None => unreachable!(),
436    };
437
438    /// The maximum theoretic possible alignment of a type.
439    ///
440    /// For compatibility with future Rust versions, this is defined as the
441    /// maximum power-of-two that fits into a `usize`. See also
442    /// [`DstLayout::CURRENT_MAX_ALIGN`].
443    const THEORETICAL_MAX_ALIGN: NonZeroUsize =
444        match NonZeroUsize::new(1 << (POINTER_WIDTH_BITS - 1)) {
445            Some(max_align) => max_align,
446            None => unreachable!(),
447        };
448
449    /// The current, documented max alignment of a type \[1\].
450    ///
451    /// \[1\] Per <https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers>:
452    ///
453    ///   The alignment value must be a power of two from 1 up to
454    ///   2<sup>29</sup>.
455    #[cfg(not(kani))]
456    const CURRENT_MAX_ALIGN: NonZeroUsize = match NonZeroUsize::new(1 << 28) {
457        Some(max_align) => max_align,
458        None => unreachable!(),
459    };
460
461    /// Constructs a `DstLayout` for a zero-sized type with `repr_align`
462    /// alignment (or 1). If `repr_align` is provided, then it must be a power
463    /// of two.
464    ///
465    /// # Panics
466    ///
467    /// This function panics if the supplied `repr_align` is not a power of two.
468    ///
469    /// # Safety
470    ///
471    /// Unsafe code may assume that the contract of this function is satisfied.
472    #[doc(hidden)]
473    #[inline]
474    pub const fn new_zst(repr_align: Option<NonZeroUsize>) -> DstLayout {
475        let align = match repr_align {
476            Some(align) => align,
477            None => Self::MIN_ALIGN,
478        };
479
480        assert!(align.is_power_of_two());
481
482        DstLayout { align, size_info: SizeInfo::Sized { _size: 0 } }
483    }
484
485    /// Constructs a `DstLayout` which describes `T`.
486    ///
487    /// # Safety
488    ///
489    /// Unsafe code may assume that `DstLayout` is the correct layout for `T`.
490    #[doc(hidden)]
491    #[inline]
492    pub const fn for_type<T>() -> DstLayout {
493        // SAFETY: `align` is correct by construction. `T: Sized`, and so it is
494        // sound to initialize `size_info` to `SizeInfo::Sized { size }`; the
495        // `size` field is also correct by construction.
496        DstLayout {
497            align: match NonZeroUsize::new(mem::align_of::<T>()) {
498                Some(align) => align,
499                None => unreachable!(),
500            },
501            size_info: SizeInfo::Sized { _size: mem::size_of::<T>() },
502        }
503    }
504
505    /// Constructs a `DstLayout` which describes `[T]`.
506    ///
507    /// # Safety
508    ///
509    /// Unsafe code may assume that `DstLayout` is the correct layout for `[T]`.
510    const fn for_slice<T>() -> DstLayout {
511        // SAFETY: The alignment of a slice is equal to the alignment of its
512        // element type, and so `align` is initialized correctly.
513        //
514        // Since this is just a slice type, there is no offset between the
515        // beginning of the type and the beginning of the slice, so it is
516        // correct to set `offset: 0`. The `elem_size` is correct by
517        // construction. Since `[T]` is a (degenerate case of a) slice DST, it
518        // is correct to initialize `size_info` to `SizeInfo::SliceDst`.
519        DstLayout {
520            align: match NonZeroUsize::new(mem::align_of::<T>()) {
521                Some(align) => align,
522                None => unreachable!(),
523            },
524            size_info: SizeInfo::SliceDst(TrailingSliceLayout {
525                _offset: 0,
526                _elem_size: mem::size_of::<T>(),
527            }),
528        }
529    }
530
531    /// Like `Layout::extend`, this creates a layout that describes a record
532    /// whose layout consists of `self` followed by `next` that includes the
533    /// necessary inter-field padding, but not any trailing padding.
534    ///
535    /// In order to match the layout of a `#[repr(C)]` struct, this method
536    /// should be invoked for each field in declaration order. To add trailing
537    /// padding, call `DstLayout::pad_to_align` after extending the layout for
538    /// all fields. If `self` corresponds to a type marked with
539    /// `repr(packed(N))`, then `repr_packed` should be set to `Some(N)`,
540    /// otherwise `None`.
541    ///
542    /// This method cannot be used to match the layout of a record with the
543    /// default representation, as that representation is mostly unspecified.
544    ///
545    /// # Safety
546    ///
547    /// If a (potentially hypothetical) valid `repr(C)` Rust type begins with
548    /// fields whose layout are `self`, and those fields are immediately
549    /// followed by a field whose layout is `field`, then unsafe code may rely
550    /// on `self.extend(field, repr_packed)` producing a layout that correctly
551    /// encompasses those two components.
552    ///
553    /// We make no guarantees to the behavior of this method if these fragments
554    /// cannot appear in a valid Rust type (e.g., the concatenation of the
555    /// layouts would lead to a size larger than `isize::MAX`).
556    #[doc(hidden)]
557    #[inline]
558    pub const fn extend(self, field: DstLayout, repr_packed: Option<NonZeroUsize>) -> Self {
559        use util::{core_layout::padding_needed_for, max, min};
560
561        // If `repr_packed` is `None`, there are no alignment constraints, and
562        // the value can be defaulted to `THEORETICAL_MAX_ALIGN`.
563        let max_align = match repr_packed {
564            Some(max_align) => max_align,
565            None => Self::THEORETICAL_MAX_ALIGN,
566        };
567
568        assert!(max_align.is_power_of_two());
569
570        // We use Kani to prove that this method is robust to future increases
571        // in Rust's maximum allowed alignment. However, if such a change ever
572        // actually occurs, we'd like to be notified via assertion failures.
573        #[cfg(not(kani))]
574        {
575            debug_assert!(self.align.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
576            debug_assert!(field.align.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
577            if let Some(repr_packed) = repr_packed {
578                debug_assert!(repr_packed.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
579            }
580        }
581
582        // The field's alignment is clamped by `repr_packed` (i.e., the
583        // `repr(packed(N))` attribute, if any) [1].
584        //
585        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
586        //
587        //   The alignments of each field, for the purpose of positioning
588        //   fields, is the smaller of the specified alignment and the alignment
589        //   of the field's type.
590        let field_align = min(field.align, max_align);
591
592        // The struct's alignment is the maximum of its previous alignment and
593        // `field_align`.
594        let align = max(self.align, field_align);
595
596        let size_info = match self.size_info {
597            // If the layout is already a DST, we panic; DSTs cannot be extended
598            // with additional fields.
599            SizeInfo::SliceDst(..) => panic!("Cannot extend a DST with additional fields."),
600
601            SizeInfo::Sized { _size: preceding_size } => {
602                // Compute the minimum amount of inter-field padding needed to
603                // satisfy the field's alignment, and offset of the trailing
604                // field. [1]
605                //
606                // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
607                //
608                //   Inter-field padding is guaranteed to be the minimum
609                //   required in order to satisfy each field's (possibly
610                //   altered) alignment.
611                let padding = padding_needed_for(preceding_size, field_align);
612
613                // This will not panic (and is proven to not panic, with Kani)
614                // if the layout components can correspond to a leading layout
615                // fragment of a valid Rust type, but may panic otherwise (e.g.,
616                // combining or aligning the components would create a size
617                // exceeding `isize::MAX`).
618                let offset = match preceding_size.checked_add(padding) {
619                    Some(offset) => offset,
620                    None => panic!("Adding padding to `self`'s size overflows `usize`."),
621                };
622
623                match field.size_info {
624                    SizeInfo::Sized { _size: field_size } => {
625                        // If the trailing field is sized, the resulting layout
626                        // will be sized. Its size will be the sum of the
627                        // preceeding layout, the size of the new field, and the
628                        // size of inter-field padding between the two.
629                        //
630                        // This will not panic (and is proven with Kani to not
631                        // panic) if the layout components can correspond to a
632                        // leading layout fragment of a valid Rust type, but may
633                        // panic otherwise (e.g., combining or aligning the
634                        // components would create a size exceeding
635                        // `usize::MAX`).
636                        let size = match offset.checked_add(field_size) {
637                            Some(size) => size,
638                            None => panic!("`field` cannot be appended without the total size overflowing `usize`"),
639                        };
640                        SizeInfo::Sized { _size: size }
641                    }
642                    SizeInfo::SliceDst(TrailingSliceLayout {
643                        _offset: trailing_offset,
644                        _elem_size,
645                    }) => {
646                        // If the trailing field is dynamically sized, so too
647                        // will the resulting layout. The offset of the trailing
648                        // slice component is the sum of the offset of the
649                        // trailing field and the trailing slice offset within
650                        // that field.
651                        //
652                        // This will not panic (and is proven with Kani to not
653                        // panic) if the layout components can correspond to a
654                        // leading layout fragment of a valid Rust type, but may
655                        // panic otherwise (e.g., combining or aligning the
656                        // components would create a size exceeding
657                        // `usize::MAX`).
658                        let offset = match offset.checked_add(trailing_offset) {
659                            Some(offset) => offset,
660                            None => panic!("`field` cannot be appended without the total size overflowing `usize`"),
661                        };
662                        SizeInfo::SliceDst(TrailingSliceLayout { _offset: offset, _elem_size })
663                    }
664                }
665            }
666        };
667
668        DstLayout { align, size_info }
669    }
670
671    /// Like `Layout::pad_to_align`, this routine rounds the size of this layout
672    /// up to the nearest multiple of this type's alignment or `repr_packed`
673    /// (whichever is less). This method leaves DST layouts unchanged, since the
674    /// trailing padding of DSTs is computed at runtime.
675    ///
676    /// In order to match the layout of a `#[repr(C)]` struct, this method
677    /// should be invoked after the invocations of [`DstLayout::extend`]. If
678    /// `self` corresponds to a type marked with `repr(packed(N))`, then
679    /// `repr_packed` should be set to `Some(N)`, otherwise `None`.
680    ///
681    /// This method cannot be used to match the layout of a record with the
682    /// default representation, as that representation is mostly unspecified.
683    ///
684    /// # Safety
685    ///
686    /// If a (potentially hypothetical) valid `repr(C)` type begins with fields
687    /// whose layout are `self` followed only by zero or more bytes of trailing
688    /// padding (not included in `self`), then unsafe code may rely on
689    /// `self.pad_to_align(repr_packed)` producing a layout that correctly
690    /// encapsulates the layout of that type.
691    ///
692    /// We make no guarantees to the behavior of this method if `self` cannot
693    /// appear in a valid Rust type (e.g., because the addition of trailing
694    /// padding would lead to a size larger than `isize::MAX`).
695    #[doc(hidden)]
696    #[inline]
697    pub const fn pad_to_align(self) -> Self {
698        use util::core_layout::padding_needed_for;
699
700        let size_info = match self.size_info {
701            // For sized layouts, we add the minimum amount of trailing padding
702            // needed to satisfy alignment.
703            SizeInfo::Sized { _size: unpadded_size } => {
704                let padding = padding_needed_for(unpadded_size, self.align);
705                let size = match unpadded_size.checked_add(padding) {
706                    Some(size) => size,
707                    None => panic!("Adding padding caused size to overflow `usize`."),
708                };
709                SizeInfo::Sized { _size: size }
710            }
711            // For DST layouts, trailing padding depends on the length of the
712            // trailing DST and is computed at runtime. This does not alter the
713            // offset or element size of the layout, so we leave `size_info`
714            // unchanged.
715            size_info @ SizeInfo::SliceDst(_) => size_info,
716        };
717
718        DstLayout { align: self.align, size_info }
719    }
720
721    /// Validates that a cast is sound from a layout perspective.
722    ///
723    /// Validates that the size and alignment requirements of a type with the
724    /// layout described in `self` would not be violated by performing a
725    /// `cast_type` cast from a pointer with address `addr` which refers to a
726    /// memory region of size `bytes_len`.
727    ///
728    /// If the cast is valid, `validate_cast_and_convert_metadata` returns
729    /// `(elems, split_at)`. If `self` describes a dynamically-sized type, then
730    /// `elems` is the maximum number of trailing slice elements for which a
731    /// cast would be valid (for sized types, `elem` is meaningless and should
732    /// be ignored). `split_at` is the index at which to split the memory region
733    /// in order for the prefix (suffix) to contain the result of the cast, and
734    /// in order for the remaining suffix (prefix) to contain the leftover
735    /// bytes.
736    ///
737    /// There are three conditions under which a cast can fail:
738    /// - The smallest possible value for the type is larger than the provided
739    ///   memory region
740    /// - A prefix cast is requested, and `addr` does not satisfy `self`'s
741    ///   alignment requirement
742    /// - A suffix cast is requested, and `addr + bytes_len` does not satisfy
743    ///   `self`'s alignment requirement (as a consequence, since all instances
744    ///   of the type are a multiple of its alignment, no size for the type will
745    ///   result in a starting address which is properly aligned)
746    ///
747    /// # Safety
748    ///
749    /// The caller may assume that this implementation is correct, and may rely
750    /// on that assumption for the soundness of their code. In particular, the
751    /// caller may assume that, if `validate_cast_and_convert_metadata` returns
752    /// `Some((elems, split_at))`, then:
753    /// - A pointer to the type (for dynamically sized types, this includes
754    ///   `elems` as its pointer metadata) describes an object of size `size <=
755    ///   bytes_len`
756    /// - If this is a prefix cast:
757    ///   - `addr` satisfies `self`'s alignment
758    ///   - `size == split_at`
759    /// - If this is a suffix cast:
760    ///   - `split_at == bytes_len - size`
761    ///   - `addr + split_at` satisfies `self`'s alignment
762    ///
763    /// Note that this method does *not* ensure that a pointer constructed from
764    /// its return values will be a valid pointer. In particular, this method
765    /// does not reason about `isize` overflow, which is a requirement of many
766    /// Rust pointer APIs, and may at some point be determined to be a validity
767    /// invariant of pointer types themselves. This should never be a problem so
768    /// long as the arguments to this method are derived from a known-valid
769    /// pointer (e.g., one derived from a safe Rust reference), but it is
770    /// nonetheless the caller's responsibility to justify that pointer
771    /// arithmetic will not overflow based on a safety argument *other than* the
772    /// mere fact that this method returned successfully.
773    ///
774    /// # Panics
775    ///
776    /// `validate_cast_and_convert_metadata` will panic if `self` describes a
777    /// DST whose trailing slice element is zero-sized.
778    ///
779    /// If `addr + bytes_len` overflows `usize`,
780    /// `validate_cast_and_convert_metadata` may panic, or it may return
781    /// incorrect results. No guarantees are made about when
782    /// `validate_cast_and_convert_metadata` will panic. The caller should not
783    /// rely on `validate_cast_and_convert_metadata` panicking in any particular
784    /// condition, even if `debug_assertions` are enabled.
785    #[allow(unused)]
786    const fn validate_cast_and_convert_metadata(
787        &self,
788        addr: usize,
789        bytes_len: usize,
790        cast_type: _CastType,
791    ) -> Option<(usize, usize)> {
792        // `debug_assert!`, but with `#[allow(clippy::arithmetic_side_effects)]`.
793        macro_rules! __debug_assert {
794            ($e:expr $(, $msg:expr)?) => {
795                debug_assert!({
796                    #[allow(clippy::arithmetic_side_effects)]
797                    let e = $e;
798                    e
799                } $(, $msg)?);
800            };
801        }
802
803        // Note that, in practice, `self` is always a compile-time constant. We
804        // do this check earlier than needed to ensure that we always panic as a
805        // result of bugs in the program (such as calling this function on an
806        // invalid type) instead of allowing this panic to be hidden if the cast
807        // would have failed anyway for runtime reasons (such as a too-small
808        // memory region).
809        //
810        // TODO(#67): Once our MSRV is 1.65, use let-else:
811        // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements
812        let size_info = match self.size_info.try_to_nonzero_elem_size() {
813            Some(size_info) => size_info,
814            None => panic!("attempted to cast to slice type with zero-sized element"),
815        };
816
817        // Precondition
818        __debug_assert!(addr.checked_add(bytes_len).is_some(), "`addr` + `bytes_len` > usize::MAX");
819
820        // Alignment checks go in their own block to avoid introducing variables
821        // into the top-level scope.
822        {
823            // We check alignment for `addr` (for prefix casts) or `addr +
824            // bytes_len` (for suffix casts). For a prefix cast, the correctness
825            // of this check is trivial - `addr` is the address the object will
826            // live at.
827            //
828            // For a suffix cast, we know that all valid sizes for the type are
829            // a multiple of the alignment (and by safety precondition, we know
830            // `DstLayout` may only describe valid Rust types). Thus, a
831            // validly-sized instance which lives at a validly-aligned address
832            // must also end at a validly-aligned address. Thus, if the end
833            // address for a suffix cast (`addr + bytes_len`) is not aligned,
834            // then no valid start address will be aligned either.
835            let offset = match cast_type {
836                _CastType::_Prefix => 0,
837                _CastType::_Suffix => bytes_len,
838            };
839
840            // Addition is guaranteed not to overflow because `offset <=
841            // bytes_len`, and `addr + bytes_len <= usize::MAX` is a
842            // precondition of this method. Modulus is guaranteed not to divide
843            // by 0 because `align` is non-zero.
844            #[allow(clippy::arithmetic_side_effects)]
845            if (addr + offset) % self.align.get() != 0 {
846                return None;
847            }
848        }
849
850        let (elems, self_bytes) = match size_info {
851            SizeInfo::Sized { _size: size } => {
852                if size > bytes_len {
853                    return None;
854                }
855                (0, size)
856            }
857            SizeInfo::SliceDst(TrailingSliceLayout { _offset: offset, _elem_size: elem_size }) => {
858                // Calculate the maximum number of bytes that could be consumed
859                // - any number of bytes larger than this will either not be a
860                // multiple of the alignment, or will be larger than
861                // `bytes_len`.
862                let max_total_bytes =
863                    util::round_down_to_next_multiple_of_alignment(bytes_len, self.align);
864                // Calculate the maximum number of bytes that could be consumed
865                // by the trailing slice.
866                //
867                // TODO(#67): Once our MSRV is 1.65, use let-else:
868                // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements
869                let max_slice_and_padding_bytes = match max_total_bytes.checked_sub(offset) {
870                    Some(max) => max,
871                    // `bytes_len` too small even for 0 trailing slice elements.
872                    None => return None,
873                };
874
875                // Calculate the number of elements that fit in
876                // `max_slice_and_padding_bytes`; any remaining bytes will be
877                // considered padding.
878                //
879                // Guaranteed not to divide by zero: `elem_size` is non-zero.
880                #[allow(clippy::arithmetic_side_effects)]
881                let elems = max_slice_and_padding_bytes / elem_size.get();
882                // Guaranteed not to overflow on multiplication: `usize::MAX >=
883                // max_slice_and_padding_bytes >= (max_slice_and_padding_bytes /
884                // elem_size) * elem_size`.
885                //
886                // Guaranteed not to overflow on addition:
887                // - max_slice_and_padding_bytes == max_total_bytes - offset
888                // - elems * elem_size <= max_slice_and_padding_bytes == max_total_bytes - offset
889                // - elems * elem_size + offset <= max_total_bytes <= usize::MAX
890                #[allow(clippy::arithmetic_side_effects)]
891                let without_padding = offset + elems * elem_size.get();
892                // `self_bytes` is equal to the offset bytes plus the bytes
893                // consumed by the trailing slice plus any padding bytes
894                // required to satisfy the alignment. Note that we have computed
895                // the maximum number of trailing slice elements that could fit
896                // in `self_bytes`, so any padding is guaranteed to be less than
897                // the size of an extra element.
898                //
899                // Guaranteed not to overflow:
900                // - By previous comment: without_padding == elems * elem_size +
901                //   offset <= max_total_bytes
902                // - By construction, `max_total_bytes` is a multiple of
903                //   `self.align`.
904                // - At most, adding padding needed to round `without_padding`
905                //   up to the next multiple of the alignment will bring
906                //   `self_bytes` up to `max_total_bytes`.
907                #[allow(clippy::arithmetic_side_effects)]
908                let self_bytes = without_padding
909                    + util::core_layout::padding_needed_for(without_padding, self.align);
910                (elems, self_bytes)
911            }
912        };
913
914        __debug_assert!(self_bytes <= bytes_len);
915
916        let split_at = match cast_type {
917            _CastType::_Prefix => self_bytes,
918            // Guaranteed not to underflow:
919            // - In the `Sized` branch, only returns `size` if `size <=
920            //   bytes_len`.
921            // - In the `SliceDst` branch, calculates `self_bytes <=
922            //   max_toatl_bytes`, which is upper-bounded by `bytes_len`.
923            #[allow(clippy::arithmetic_side_effects)]
924            _CastType::_Suffix => bytes_len - self_bytes,
925        };
926
927        Some((elems, split_at))
928    }
929}
930
931/// A trait which carries information about a type's layout that is used by the
932/// internals of this crate.
933///
934/// This trait is not meant for consumption by code outside of this crate. While
935/// the normal semver stability guarantees apply with respect to which types
936/// implement this trait and which trait implementations are implied by this
937/// trait, no semver stability guarantees are made regarding its internals; they
938/// may change at any time, and code which makes use of them may break.
939///
940/// # Safety
941///
942/// This trait does not convey any safety guarantees to code outside this crate.
943#[doc(hidden)] // TODO: Remove this once KnownLayout is used by other APIs
944pub unsafe trait KnownLayout {
945    // The `Self: Sized` bound makes it so that `KnownLayout` can still be
946    // object safe. It's not currently object safe thanks to `const LAYOUT`, and
947    // it likely won't be in the future, but there's no reason not to be
948    // forwards-compatible with object safety.
949    #[doc(hidden)]
950    fn only_derive_is_allowed_to_implement_this_trait()
951    where
952        Self: Sized;
953
954    #[doc(hidden)]
955    const LAYOUT: DstLayout;
956
957    /// SAFETY: The returned pointer has the same address and provenance as
958    /// `bytes`. If `Self` is a DST, the returned pointer's referent has `elems`
959    /// elements in its trailing slice. If `Self` is sized, `elems` is ignored.
960    #[doc(hidden)]
961    fn raw_from_ptr_len(bytes: NonNull<u8>, elems: usize) -> NonNull<Self>;
962}
963
964// SAFETY: Delegates safety to `DstLayout::for_slice`.
965unsafe impl<T: KnownLayout> KnownLayout for [T] {
966    #[allow(clippy::missing_inline_in_public_items)]
967    fn only_derive_is_allowed_to_implement_this_trait()
968    where
969        Self: Sized,
970    {
971    }
972    const LAYOUT: DstLayout = DstLayout::for_slice::<T>();
973
974    // SAFETY: `.cast` preserves address and provenance. The returned pointer
975    // refers to an object with `elems` elements by construction.
976    #[inline(always)]
977    fn raw_from_ptr_len(data: NonNull<u8>, elems: usize) -> NonNull<Self> {
978        // TODO(#67): Remove this allow. See NonNullExt for more details.
979        #[allow(unstable_name_collisions)]
980        NonNull::slice_from_raw_parts(data.cast::<T>(), elems)
981    }
982}
983
984#[rustfmt::skip]
985impl_known_layout!(
986    (),
987    u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64,
988    bool, char,
989    NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32,
990    NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize
991);
992#[rustfmt::skip]
993impl_known_layout!(
994    T         => Option<T>,
995    T: ?Sized => PhantomData<T>,
996    T         => Wrapping<T>,
997    T         => MaybeUninit<T>,
998    T: ?Sized => *const T,
999    T: ?Sized => *mut T,
1000);
1001impl_known_layout!(const N: usize, T => [T; N]);
1002
1003safety_comment! {
1004    /// SAFETY:
1005    /// `str` and `ManuallyDrop<[T]>` [1] have the same representations as
1006    /// `[u8]` and `[T]` repsectively. `str` has different bit validity than
1007    /// `[u8]`, but that doesn't affect the soundness of this impl.
1008    ///
1009    /// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
1010    ///
1011    ///   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
1012    ///   validity as `T`
1013    ///
1014    /// TODO(#429):
1015    /// -  Add quotes from docs.
1016    /// -  Once [1] (added in
1017    /// https://github.com/rust-lang/rust/pull/115522) is available on stable,
1018    /// quote the stable docs instead of the nightly docs.
1019    unsafe_impl_known_layout!(#[repr([u8])] str);
1020    unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] ManuallyDrop<T>);
1021}
1022
1023/// Analyzes whether a type is [`FromZeroes`].
1024///
1025/// This derive analyzes, at compile time, whether the annotated type satisfies
1026/// the [safety conditions] of `FromZeroes` and implements `FromZeroes` if it is
1027/// sound to do so. This derive can be applied to structs, enums, and unions;
1028/// e.g.:
1029///
1030/// ```
1031/// # use zerocopy_derive::FromZeroes;
1032/// #[derive(FromZeroes)]
1033/// struct MyStruct {
1034/// # /*
1035///     ...
1036/// # */
1037/// }
1038///
1039/// #[derive(FromZeroes)]
1040/// #[repr(u8)]
1041/// enum MyEnum {
1042/// #   Variant0,
1043/// # /*
1044///     ...
1045/// # */
1046/// }
1047///
1048/// #[derive(FromZeroes)]
1049/// union MyUnion {
1050/// #   variant: u8,
1051/// # /*
1052///     ...
1053/// # */
1054/// }
1055/// ```
1056///
1057/// [safety conditions]: trait@FromZeroes#safety
1058///
1059/// # Analysis
1060///
1061/// *This section describes, roughly, the analysis performed by this derive to
1062/// determine whether it is sound to implement `FromZeroes` for a given type.
1063/// Unless you are modifying the implementation of this derive, or attempting to
1064/// manually implement `FromZeroes` for a type yourself, you don't need to read
1065/// this section.*
1066///
1067/// If a type has the following properties, then this derive can implement
1068/// `FromZeroes` for that type:
1069///
1070/// - If the type is a struct, all of its fields must be `FromZeroes`.
1071/// - If the type is an enum, it must be C-like (meaning that all variants have
1072///   no fields) and it must have a variant with a discriminant of `0`. See [the
1073///   reference] for a description of how discriminant values are chosen.
1074/// - The type must not contain any [`UnsafeCell`]s (this is required in order
1075///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
1076///   memory). The type may contain references or pointers to `UnsafeCell`s so
1077///   long as those values can themselves be initialized from zeroes
1078///   (`FromZeroes` is not currently implemented for, e.g.,
1079///   `Option<&UnsafeCell<_>>`, but it could be one day).
1080///
1081/// This analysis is subject to change. Unsafe code may *only* rely on the
1082/// documented [safety conditions] of `FromZeroes`, and must *not* rely on the
1083/// implementation details of this derive.
1084///
1085/// [the reference]: https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
1086/// [`UnsafeCell`]: core::cell::UnsafeCell
1087///
1088/// ## Why isn't an explicit representation required for structs?
1089///
1090/// Neither this derive, nor the [safety conditions] of `FromZeroes`, requires
1091/// that structs are marked with `#[repr(C)]`.
1092///
1093/// Per the [Rust reference](reference),
1094///
1095/// > The representation of a type can change the padding between fields, but
1096/// > does not change the layout of the fields themselves.
1097///
1098/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
1099///
1100/// Since the layout of structs only consists of padding bytes and field bytes,
1101/// a struct is soundly `FromZeroes` if:
1102/// 1. its padding is soundly `FromZeroes`, and
1103/// 2. its fields are soundly `FromZeroes`.
1104///
1105/// The answer to the first question is always yes: padding bytes do not have
1106/// any validity constraints. A [discussion] of this question in the Unsafe Code
1107/// Guidelines Working Group concluded that it would be virtually unimaginable
1108/// for future versions of rustc to add validity constraints to padding bytes.
1109///
1110/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
1111///
1112/// Whether a struct is soundly `FromZeroes` therefore solely depends on whether
1113/// its fields are `FromZeroes`.
1114// TODO(#146): Document why we don't require an enum to have an explicit `repr`
1115// attribute.
1116#[cfg(any(feature = "derive", test))]
1117#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1118pub use zerocopy_derive::FromZeroes;
1119
1120/// Types whose validity can be checked at runtime, allowing them to be
1121/// conditionally converted from byte slices.
1122///
1123/// WARNING: Do not implement this trait yourself! Instead, use
1124/// `#[derive(TryFromBytes)]`.
1125///
1126/// `TryFromBytes` types can safely be deserialized from an untrusted sequence
1127/// of bytes by performing a runtime check that the byte sequence contains a
1128/// valid instance of `Self`.
1129///
1130/// `TryFromBytes` is ignorant of byte order. For byte order-aware types, see
1131/// the [`byteorder`] module.
1132///
1133/// # What is a "valid instance"?
1134///
1135/// In Rust, each type has *bit validity*, which refers to the set of bit
1136/// patterns which may appear in an instance of that type. It is impossible for
1137/// safe Rust code to produce values which violate bit validity (ie, values
1138/// outside of the "valid" set of bit patterns). If `unsafe` code produces an
1139/// invalid value, this is considered [undefined behavior].
1140///
1141/// Rust's bit validity rules are currently being decided, which means that some
1142/// types have three classes of bit patterns: those which are definitely valid,
1143/// and whose validity is documented in the language; those which may or may not
1144/// be considered valid at some point in the future; and those which are
1145/// definitely invalid.
1146///
1147/// Zerocopy takes a conservative approach, and only considers a bit pattern to
1148/// be valid if its validity is a documenteed guarantee provided by the
1149/// language.
1150///
1151/// For most use cases, Rust's current guarantees align with programmers'
1152/// intuitions about what ought to be valid. As a result, zerocopy's
1153/// conservatism should not affect most users. One notable exception is unions,
1154/// whose bit validity is very up in the air; zerocopy does not permit
1155/// implementing `TryFromBytes` for any union type.
1156///
1157/// If you are negatively affected by lack of support for a particular type,
1158/// we encourage you to let us know by [filing an issue][github-repo].
1159///
1160/// # Safety
1161///
1162/// On its own, `T: TryFromBytes` does not make any guarantees about the layout
1163/// or representation of `T`. It merely provides the ability to perform a
1164/// validity check at runtime via methods like [`try_from_ref`].
1165///
1166/// Currently, it is not possible to stably implement `TryFromBytes` other than
1167/// by using `#[derive(TryFromBytes)]`. While there are `#[doc(hidden)]` items
1168/// on this trait that provide well-defined safety invariants, no stability
1169/// guarantees are made with respect to these items. In particular, future
1170/// releases of zerocopy may make backwards-breaking changes to these items,
1171/// including changes that only affect soundness, which may cause code which
1172/// uses those items to silently become unsound.
1173///
1174/// [undefined behavior]: https://raphlinus.github.io/programming/rust/2018/08/17/undefined-behavior.html
1175/// [github-repo]: https://github.com/google/zerocopy
1176/// [`try_from_ref`]: TryFromBytes::try_from_ref
1177// TODO(#5): Update `try_from_ref` doc link once it exists
1178#[doc(hidden)]
1179pub unsafe trait TryFromBytes {
1180    /// Does a given memory range contain a valid instance of `Self`?
1181    ///
1182    /// # Safety
1183    ///
1184    /// ## Preconditions
1185    ///
1186    /// The memory referenced by `candidate` may only be accessed via reads for
1187    /// the duration of this method call. This prohibits writes through mutable
1188    /// references and through [`UnsafeCell`]s. There may exist immutable
1189    /// references to the same memory which contain `UnsafeCell`s so long as:
1190    /// - Those `UnsafeCell`s exist at the same byte ranges as `UnsafeCell`s in
1191    ///   `Self`. This is a bidirectional property: `Self` may not contain
1192    ///   `UnsafeCell`s where other references to the same memory do not, and
1193    ///   vice-versa.
1194    /// - Those `UnsafeCell`s are never used to perform mutation for the
1195    ///   duration of this method call.
1196    ///
1197    /// The memory referenced by `candidate` may not be referenced by any
1198    /// mutable references even if these references are not used to perform
1199    /// mutation.
1200    ///
1201    /// `candidate` is not required to refer to a valid `Self`. However, it must
1202    /// satisfy the requirement that uninitialized bytes may only be present
1203    /// where it is possible for them to be present in `Self`. This is a dynamic
1204    /// property: if, at a particular byte offset, a valid enum discriminant is
1205    /// set, the subsequent bytes may only have uninitialized bytes as
1206    /// specificed by the corresponding enum.
1207    ///
1208    /// Formally, given `len = size_of_val_raw(candidate)`, at every byte
1209    /// offset, `b`, in the range `[0, len)`:
1210    /// - If, in all instances `s: Self` of length `len`, the byte at offset `b`
1211    ///   in `s` is initialized, then the byte at offset `b` within `*candidate`
1212    ///   must be initialized.
1213    /// - Let `c` be the contents of the byte range `[0, b)` in `*candidate`.
1214    ///   Let `S` be the subset of valid instances of `Self` of length `len`
1215    ///   which contain `c` in the offset range `[0, b)`. If, for all instances
1216    ///   of `s: Self` in `S`, the byte at offset `b` in `s` is initialized,
1217    ///   then the byte at offset `b` in `*candidate` must be initialized.
1218    ///
1219    ///   Pragmatically, this means that if `*candidate` is guaranteed to
1220    ///   contain an enum type at a particular offset, and the enum discriminant
1221    ///   stored in `*candidate` corresponds to a valid variant of that enum
1222    ///   type, then it is guaranteed that the appropriate bytes of `*candidate`
1223    ///   are initialized as defined by that variant's bit validity (although
1224    ///   note that the variant may contain another enum type, in which case the
1225    ///   same rules apply depending on the state of its discriminant, and so on
1226    ///   recursively).
1227    ///
1228    /// ## Postconditions
1229    ///
1230    /// Unsafe code may assume that, if `is_bit_valid(candidate)` returns true,
1231    /// `*candidate` contains a valid `Self`.
1232    ///
1233    /// # Panics
1234    ///
1235    /// `is_bit_valid` may panic. Callers are responsible for ensuring that any
1236    /// `unsafe` code remains sound even in the face of `is_bit_valid`
1237    /// panicking. (We support user-defined validation routines; so long as
1238    /// these routines are not required to be `unsafe`, there is no way to
1239    /// ensure that these do not generate panics.)
1240    ///
1241    /// [`UnsafeCell`]: core::cell::UnsafeCell
1242    #[doc(hidden)]
1243    unsafe fn is_bit_valid(candidate: Ptr<'_, Self>) -> bool;
1244
1245    /// Attempts to interpret a byte slice as a `Self`.
1246    ///
1247    /// `try_from_ref` validates that `bytes` contains a valid `Self`, and that
1248    /// it satisfies `Self`'s alignment requirement. If it does, then `bytes` is
1249    /// reinterpreted as a `Self`.
1250    ///
1251    /// Note that Rust's bit validity rules are still being decided. As such,
1252    /// there exist types whose bit validity is ambiguous. See the
1253    /// `TryFromBytes` docs for a discussion of how these cases are handled.
1254    // TODO(#251): In a future in which we distinguish between `FromBytes` and
1255    // `RefFromBytes`, this requires `where Self: RefFromBytes` to disallow
1256    // interior mutability.
1257    #[inline]
1258    #[doc(hidden)] // TODO(#5): Finalize name before remove this attribute.
1259    fn try_from_ref(bytes: &[u8]) -> Option<&Self>
1260    where
1261        Self: KnownLayout,
1262    {
1263        let maybe_self = Ptr::from(bytes).try_cast_into_no_leftover::<Self>()?;
1264
1265        // SAFETY:
1266        // - Since `bytes` is an immutable reference, we know that no mutable
1267        //   references exist to this memory region.
1268        // - Since `[u8]` contains no `UnsafeCell`s, we know there are no
1269        //   `&UnsafeCell` references to this memory region.
1270        // - Since we don't permit implementing `TryFromBytes` for types which
1271        //   contain `UnsafeCell`s, there are no `UnsafeCell`s in `Self`, and so
1272        //   the requirement that all references contain `UnsafeCell`s at the
1273        //   same offsets is trivially satisfied.
1274        // - All bytes of `bytes` are initialized.
1275        //
1276        // This call may panic. If that happens, it doesn't cause any soundness
1277        // issues, as we have not generated any invalid state which we need to
1278        // fix before returning.
1279        if unsafe { !Self::is_bit_valid(maybe_self) } {
1280            return None;
1281        }
1282
1283        // SAFETY:
1284        // - Preconditions for `as_ref`:
1285        //   - `is_bit_valid` guarantees that `*maybe_self` contains a valid
1286        //     `Self`. Since `&[u8]` does not permit interior mutation, this
1287        //     cannot be invalidated after this method returns.
1288        //   - Since the argument and return types are immutable references,
1289        //     Rust will prevent the caller from producing any mutable
1290        //     references to the same memory region.
1291        //   - Since `Self` is not allowed to contain any `UnsafeCell`s and the
1292        //     same is true of `[u8]`, interior mutation is not possible. Thus,
1293        //     no mutation is possible. For the same reason, there is no
1294        //     mismatch between the two types in terms of which byte ranges are
1295        //     referenced as `UnsafeCell`s.
1296        // - Since interior mutation isn't possible within `Self`, there's no
1297        //   way for the returned reference to be used to modify the byte range,
1298        //   and thus there's no way for the returned reference to be used to
1299        //   write an invalid `[u8]` which would be observable via the original
1300        //   `&[u8]`.
1301        Some(unsafe { maybe_self.as_ref() })
1302    }
1303}
1304
1305/// Types for which a sequence of bytes all set to zero represents a valid
1306/// instance of the type.
1307///
1308/// Any memory region of the appropriate length which is guaranteed to contain
1309/// only zero bytes can be viewed as any `FromZeroes` type with no runtime
1310/// overhead. This is useful whenever memory is known to be in a zeroed state,
1311/// such memory returned from some allocation routines.
1312///
1313/// # Implementation
1314///
1315/// **Do not implement this trait yourself!** Instead, use
1316/// [`#[derive(FromZeroes)]`][derive] (requires the `derive` Cargo feature);
1317/// e.g.:
1318///
1319/// ```
1320/// # use zerocopy_derive::FromZeroes;
1321/// #[derive(FromZeroes)]
1322/// struct MyStruct {
1323/// # /*
1324///     ...
1325/// # */
1326/// }
1327///
1328/// #[derive(FromZeroes)]
1329/// #[repr(u8)]
1330/// enum MyEnum {
1331/// #   Variant0,
1332/// # /*
1333///     ...
1334/// # */
1335/// }
1336///
1337/// #[derive(FromZeroes)]
1338/// union MyUnion {
1339/// #   variant: u8,
1340/// # /*
1341///     ...
1342/// # */
1343/// }
1344/// ```
1345///
1346/// This derive performs a sophisticated, compile-time safety analysis to
1347/// determine whether a type is `FromZeroes`.
1348///
1349/// # Safety
1350///
1351/// *This section describes what is required in order for `T: FromZeroes`, and
1352/// what unsafe code may assume of such types. If you don't plan on implementing
1353/// `FromZeroes` manually, and you don't plan on writing unsafe code that
1354/// operates on `FromZeroes` types, then you don't need to read this section.*
1355///
1356/// If `T: FromZeroes`, then unsafe code may assume that:
1357/// - It is sound to treat any initialized sequence of zero bytes of length
1358///   `size_of::<T>()` as a `T`.
1359/// - Given `b: &[u8]` where `b.len() == size_of::<T>()`, `b` is aligned to
1360///   `align_of::<T>()`, and `b` contains only zero bytes, it is sound to
1361///   construct a `t: &T` at the same address as `b`, and it is sound for both
1362///   `b` and `t` to be live at the same time.
1363///
1364/// If a type is marked as `FromZeroes` which violates this contract, it may
1365/// cause undefined behavior.
1366///
1367/// `#[derive(FromZeroes)]` only permits [types which satisfy these
1368/// requirements][derive-analysis].
1369///
1370#[cfg_attr(
1371    feature = "derive",
1372    doc = "[derive]: zerocopy_derive::FromZeroes",
1373    doc = "[derive-analysis]: zerocopy_derive::FromZeroes#analysis"
1374)]
1375#[cfg_attr(
1376    not(feature = "derive"),
1377    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeroes.html"),
1378    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeroes.html#analysis"),
1379)]
1380pub unsafe trait FromZeroes {
1381    // The `Self: Sized` bound makes it so that `FromZeroes` is still object
1382    // safe.
1383    #[doc(hidden)]
1384    fn only_derive_is_allowed_to_implement_this_trait()
1385    where
1386        Self: Sized;
1387
1388    /// Overwrites `self` with zeroes.
1389    ///
1390    /// Sets every byte in `self` to 0. While this is similar to doing `*self =
1391    /// Self::new_zeroed()`, it differs in that `zero` does not semantically
1392    /// drop the current value and replace it with a new one - it simply
1393    /// modifies the bytes of the existing value.
1394    ///
1395    /// # Examples
1396    ///
1397    /// ```
1398    /// # use zerocopy::FromZeroes;
1399    /// # use zerocopy_derive::*;
1400    /// #
1401    /// #[derive(FromZeroes)]
1402    /// #[repr(C)]
1403    /// struct PacketHeader {
1404    ///     src_port: [u8; 2],
1405    ///     dst_port: [u8; 2],
1406    ///     length: [u8; 2],
1407    ///     checksum: [u8; 2],
1408    /// }
1409    ///
1410    /// let mut header = PacketHeader {
1411    ///     src_port: 100u16.to_be_bytes(),
1412    ///     dst_port: 200u16.to_be_bytes(),
1413    ///     length: 300u16.to_be_bytes(),
1414    ///     checksum: 400u16.to_be_bytes(),
1415    /// };
1416    ///
1417    /// header.zero();
1418    ///
1419    /// assert_eq!(header.src_port, [0, 0]);
1420    /// assert_eq!(header.dst_port, [0, 0]);
1421    /// assert_eq!(header.length, [0, 0]);
1422    /// assert_eq!(header.checksum, [0, 0]);
1423    /// ```
1424    #[inline(always)]
1425    fn zero(&mut self) {
1426        let slf: *mut Self = self;
1427        let len = mem::size_of_val(self);
1428        // SAFETY:
1429        // - `self` is guaranteed by the type system to be valid for writes of
1430        //   size `size_of_val(self)`.
1431        // - `u8`'s alignment is 1, and thus `self` is guaranteed to be aligned
1432        //   as required by `u8`.
1433        // - Since `Self: FromZeroes`, the all-zeroes instance is a valid
1434        //   instance of `Self.`
1435        //
1436        // TODO(#429): Add references to docs and quotes.
1437        unsafe { ptr::write_bytes(slf.cast::<u8>(), 0, len) };
1438    }
1439
1440    /// Creates an instance of `Self` from zeroed bytes.
1441    ///
1442    /// # Examples
1443    ///
1444    /// ```
1445    /// # use zerocopy::FromZeroes;
1446    /// # use zerocopy_derive::*;
1447    /// #
1448    /// #[derive(FromZeroes)]
1449    /// #[repr(C)]
1450    /// struct PacketHeader {
1451    ///     src_port: [u8; 2],
1452    ///     dst_port: [u8; 2],
1453    ///     length: [u8; 2],
1454    ///     checksum: [u8; 2],
1455    /// }
1456    ///
1457    /// let header: PacketHeader = FromZeroes::new_zeroed();
1458    ///
1459    /// assert_eq!(header.src_port, [0, 0]);
1460    /// assert_eq!(header.dst_port, [0, 0]);
1461    /// assert_eq!(header.length, [0, 0]);
1462    /// assert_eq!(header.checksum, [0, 0]);
1463    /// ```
1464    #[inline(always)]
1465    fn new_zeroed() -> Self
1466    where
1467        Self: Sized,
1468    {
1469        // SAFETY: `FromZeroes` says that the all-zeroes bit pattern is legal.
1470        unsafe { mem::zeroed() }
1471    }
1472
1473    /// Creates a `Box<Self>` from zeroed bytes.
1474    ///
1475    /// This function is useful for allocating large values on the heap and
1476    /// zero-initializing them, without ever creating a temporary instance of
1477    /// `Self` on the stack. For example, `<[u8; 1048576]>::new_box_zeroed()`
1478    /// will allocate `[u8; 1048576]` directly on the heap; it does not require
1479    /// storing `[u8; 1048576]` in a temporary variable on the stack.
1480    ///
1481    /// On systems that use a heap implementation that supports allocating from
1482    /// pre-zeroed memory, using `new_box_zeroed` (or related functions) may
1483    /// have performance benefits.
1484    ///
1485    /// Note that `Box<Self>` can be converted to `Arc<Self>` and other
1486    /// container types without reallocation.
1487    ///
1488    /// # Panics
1489    ///
1490    /// Panics if allocation of `size_of::<Self>()` bytes fails.
1491    #[cfg(feature = "alloc")]
1492    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
1493    #[inline]
1494    fn new_box_zeroed() -> Box<Self>
1495    where
1496        Self: Sized,
1497    {
1498        // If `T` is a ZST, then return a proper boxed instance of it. There is
1499        // no allocation, but `Box` does require a correct dangling pointer.
1500        let layout = Layout::new::<Self>();
1501        if layout.size() == 0 {
1502            return Box::new(Self::new_zeroed());
1503        }
1504
1505        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1506        #[allow(clippy::undocumented_unsafe_blocks)]
1507        let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
1508        if ptr.is_null() {
1509            alloc::alloc::handle_alloc_error(layout);
1510        }
1511        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1512        #[allow(clippy::undocumented_unsafe_blocks)]
1513        unsafe {
1514            Box::from_raw(ptr)
1515        }
1516    }
1517
1518    /// Creates a `Box<[Self]>` (a boxed slice) from zeroed bytes.
1519    ///
1520    /// This function is useful for allocating large values of `[Self]` on the
1521    /// heap and zero-initializing them, without ever creating a temporary
1522    /// instance of `[Self; _]` on the stack. For example,
1523    /// `u8::new_box_slice_zeroed(1048576)` will allocate the slice directly on
1524    /// the heap; it does not require storing the slice on the stack.
1525    ///
1526    /// On systems that use a heap implementation that supports allocating from
1527    /// pre-zeroed memory, using `new_box_slice_zeroed` may have performance
1528    /// benefits.
1529    ///
1530    /// If `Self` is a zero-sized type, then this function will return a
1531    /// `Box<[Self]>` that has the correct `len`. Such a box cannot contain any
1532    /// actual information, but its `len()` property will report the correct
1533    /// value.
1534    ///
1535    /// # Panics
1536    ///
1537    /// * Panics if `size_of::<Self>() * len` overflows.
1538    /// * Panics if allocation of `size_of::<Self>() * len` bytes fails.
1539    #[cfg(feature = "alloc")]
1540    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
1541    #[inline]
1542    fn new_box_slice_zeroed(len: usize) -> Box<[Self]>
1543    where
1544        Self: Sized,
1545    {
1546        let size = mem::size_of::<Self>()
1547            .checked_mul(len)
1548            .expect("mem::size_of::<Self>() * len overflows `usize`");
1549        let align = mem::align_of::<Self>();
1550        // On stable Rust versions <= 1.64.0, `Layout::from_size_align` has a
1551        // bug in which sufficiently-large allocations (those which, when
1552        // rounded up to the alignment, overflow `isize`) are not rejected,
1553        // which can cause undefined behavior. See #64 for details.
1554        //
1555        // TODO(#67): Once our MSRV is > 1.64.0, remove this assertion.
1556        #[allow(clippy::as_conversions)]
1557        let max_alloc = (isize::MAX as usize).saturating_sub(align);
1558        assert!(size <= max_alloc);
1559        // TODO(https://github.com/rust-lang/rust/issues/55724): Use
1560        // `Layout::repeat` once it's stabilized.
1561        let layout =
1562            Layout::from_size_align(size, align).expect("total allocation size overflows `isize`");
1563
1564        let ptr = if layout.size() != 0 {
1565            // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1566            #[allow(clippy::undocumented_unsafe_blocks)]
1567            let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
1568            if ptr.is_null() {
1569                alloc::alloc::handle_alloc_error(layout);
1570            }
1571            ptr
1572        } else {
1573            // `Box<[T]>` does not allocate when `T` is zero-sized or when `len`
1574            // is zero, but it does require a non-null dangling pointer for its
1575            // allocation.
1576            NonNull::<Self>::dangling().as_ptr()
1577        };
1578
1579        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1580        #[allow(clippy::undocumented_unsafe_blocks)]
1581        unsafe {
1582            Box::from_raw(slice::from_raw_parts_mut(ptr, len))
1583        }
1584    }
1585
1586    /// Creates a `Vec<Self>` from zeroed bytes.
1587    ///
1588    /// This function is useful for allocating large values of `Vec`s and
1589    /// zero-initializing them, without ever creating a temporary instance of
1590    /// `[Self; _]` (or many temporary instances of `Self`) on the stack. For
1591    /// example, `u8::new_vec_zeroed(1048576)` will allocate directly on the
1592    /// heap; it does not require storing intermediate values on the stack.
1593    ///
1594    /// On systems that use a heap implementation that supports allocating from
1595    /// pre-zeroed memory, using `new_vec_zeroed` may have performance benefits.
1596    ///
1597    /// If `Self` is a zero-sized type, then this function will return a
1598    /// `Vec<Self>` that has the correct `len`. Such a `Vec` cannot contain any
1599    /// actual information, but its `len()` property will report the correct
1600    /// value.
1601    ///
1602    /// # Panics
1603    ///
1604    /// * Panics if `size_of::<Self>() * len` overflows.
1605    /// * Panics if allocation of `size_of::<Self>() * len` bytes fails.
1606    #[cfg(feature = "alloc")]
1607    #[cfg_attr(doc_cfg, doc(cfg(feature = "new_vec_zeroed")))]
1608    #[inline(always)]
1609    fn new_vec_zeroed(len: usize) -> Vec<Self>
1610    where
1611        Self: Sized,
1612    {
1613        Self::new_box_slice_zeroed(len).into()
1614    }
1615}
1616
1617/// Analyzes whether a type is [`FromBytes`].
1618///
1619/// This derive analyzes, at compile time, whether the annotated type satisfies
1620/// the [safety conditions] of `FromBytes` and implements `FromBytes` if it is
1621/// sound to do so. This derive can be applied to structs, enums, and unions;
1622/// e.g.:
1623///
1624/// ```
1625/// # use zerocopy_derive::{FromBytes, FromZeroes};
1626/// #[derive(FromZeroes, FromBytes)]
1627/// struct MyStruct {
1628/// # /*
1629///     ...
1630/// # */
1631/// }
1632///
1633/// #[derive(FromZeroes, FromBytes)]
1634/// #[repr(u8)]
1635/// enum MyEnum {
1636/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
1637/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
1638/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
1639/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
1640/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
1641/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
1642/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
1643/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
1644/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
1645/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
1646/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
1647/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
1648/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
1649/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
1650/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
1651/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
1652/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
1653/// #   VFF,
1654/// # /*
1655///     ...
1656/// # */
1657/// }
1658///
1659/// #[derive(FromZeroes, FromBytes)]
1660/// union MyUnion {
1661/// #   variant: u8,
1662/// # /*
1663///     ...
1664/// # */
1665/// }
1666/// ```
1667///
1668/// [safety conditions]: trait@FromBytes#safety
1669///
1670/// # Analysis
1671///
1672/// *This section describes, roughly, the analysis performed by this derive to
1673/// determine whether it is sound to implement `FromBytes` for a given type.
1674/// Unless you are modifying the implementation of this derive, or attempting to
1675/// manually implement `FromBytes` for a type yourself, you don't need to read
1676/// this section.*
1677///
1678/// If a type has the following properties, then this derive can implement
1679/// `FromBytes` for that type:
1680///
1681/// - If the type is a struct, all of its fields must be `FromBytes`.
1682/// - If the type is an enum:
1683///   - It must be a C-like enum (meaning that all variants have no fields).
1684///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
1685///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
1686///   - The maximum number of discriminants must be used (so that every possible
1687///     bit pattern is a valid one). Be very careful when using the `C`,
1688///     `usize`, or `isize` representations, as their size is
1689///     platform-dependent.
1690/// - The type must not contain any [`UnsafeCell`]s (this is required in order
1691///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
1692///   memory). The type may contain references or pointers to `UnsafeCell`s so
1693///   long as those values can themselves be initialized from zeroes
1694///   (`FromBytes` is not currently implemented for, e.g., `Option<*const
1695///   UnsafeCell<_>>`, but it could be one day).
1696///
1697/// [`UnsafeCell`]: core::cell::UnsafeCell
1698///
1699/// This analysis is subject to change. Unsafe code may *only* rely on the
1700/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
1701/// implementation details of this derive.
1702///
1703/// ## Why isn't an explicit representation required for structs?
1704///
1705/// Neither this derive, nor the [safety conditions] of `FromBytes`, requires
1706/// that structs are marked with `#[repr(C)]`.
1707///
1708/// Per the [Rust reference](reference),
1709///
1710/// > The representation of a type can change the padding between fields, but
1711/// > does not change the layout of the fields themselves.
1712///
1713/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
1714///
1715/// Since the layout of structs only consists of padding bytes and field bytes,
1716/// a struct is soundly `FromBytes` if:
1717/// 1. its padding is soundly `FromBytes`, and
1718/// 2. its fields are soundly `FromBytes`.
1719///
1720/// The answer to the first question is always yes: padding bytes do not have
1721/// any validity constraints. A [discussion] of this question in the Unsafe Code
1722/// Guidelines Working Group concluded that it would be virtually unimaginable
1723/// for future versions of rustc to add validity constraints to padding bytes.
1724///
1725/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
1726///
1727/// Whether a struct is soundly `FromBytes` therefore solely depends on whether
1728/// its fields are `FromBytes`.
1729// TODO(#146): Document why we don't require an enum to have an explicit `repr`
1730// attribute.
1731#[cfg(any(feature = "derive", test))]
1732#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1733pub use zerocopy_derive::FromBytes;
1734
1735/// Types for which any bit pattern is valid.
1736///
1737/// Any memory region of the appropriate length which contains initialized bytes
1738/// can be viewed as any `FromBytes` type with no runtime overhead. This is
1739/// useful for efficiently parsing bytes as structured data.
1740///
1741/// # Implementation
1742///
1743/// **Do not implement this trait yourself!** Instead, use
1744/// [`#[derive(FromBytes)]`][derive] (requires the `derive` Cargo feature);
1745/// e.g.:
1746///
1747/// ```
1748/// # use zerocopy_derive::{FromBytes, FromZeroes};
1749/// #[derive(FromZeroes, FromBytes)]
1750/// struct MyStruct {
1751/// # /*
1752///     ...
1753/// # */
1754/// }
1755///
1756/// #[derive(FromZeroes, FromBytes)]
1757/// #[repr(u8)]
1758/// enum MyEnum {
1759/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
1760/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
1761/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
1762/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
1763/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
1764/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
1765/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
1766/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
1767/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
1768/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
1769/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
1770/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
1771/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
1772/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
1773/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
1774/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
1775/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
1776/// #   VFF,
1777/// # /*
1778///     ...
1779/// # */
1780/// }
1781///
1782/// #[derive(FromZeroes, FromBytes)]
1783/// union MyUnion {
1784/// #   variant: u8,
1785/// # /*
1786///     ...
1787/// # */
1788/// }
1789/// ```
1790///
1791/// This derive performs a sophisticated, compile-time safety analysis to
1792/// determine whether a type is `FromBytes`.
1793///
1794/// # Safety
1795///
1796/// *This section describes what is required in order for `T: FromBytes`, and
1797/// what unsafe code may assume of such types. If you don't plan on implementing
1798/// `FromBytes` manually, and you don't plan on writing unsafe code that
1799/// operates on `FromBytes` types, then you don't need to read this section.*
1800///
1801/// If `T: FromBytes`, then unsafe code may assume that:
1802/// - It is sound to treat any initialized sequence of bytes of length
1803///   `size_of::<T>()` as a `T`.
1804/// - Given `b: &[u8]` where `b.len() == size_of::<T>()`, `b` is aligned to
1805///   `align_of::<T>()` it is sound to construct a `t: &T` at the same address
1806///   as `b`, and it is sound for both `b` and `t` to be live at the same time.
1807///
1808/// If a type is marked as `FromBytes` which violates this contract, it may
1809/// cause undefined behavior.
1810///
1811/// `#[derive(FromBytes)]` only permits [types which satisfy these
1812/// requirements][derive-analysis].
1813///
1814#[cfg_attr(
1815    feature = "derive",
1816    doc = "[derive]: zerocopy_derive::FromBytes",
1817    doc = "[derive-analysis]: zerocopy_derive::FromBytes#analysis"
1818)]
1819#[cfg_attr(
1820    not(feature = "derive"),
1821    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html"),
1822    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html#analysis"),
1823)]
1824pub unsafe trait FromBytes: FromZeroes {
1825    // The `Self: Sized` bound makes it so that `FromBytes` is still object
1826    // safe.
1827    #[doc(hidden)]
1828    fn only_derive_is_allowed_to_implement_this_trait()
1829    where
1830        Self: Sized;
1831
1832    /// Interprets the given `bytes` as a `&Self` without copying.
1833    ///
1834    /// If `bytes.len() != size_of::<Self>()` or `bytes` is not aligned to
1835    /// `align_of::<Self>()`, this returns `None`.
1836    ///
1837    /// # Examples
1838    ///
1839    /// ```
1840    /// use zerocopy::FromBytes;
1841    /// # use zerocopy_derive::*;
1842    ///
1843    /// #[derive(FromZeroes, FromBytes)]
1844    /// #[repr(C)]
1845    /// struct PacketHeader {
1846    ///     src_port: [u8; 2],
1847    ///     dst_port: [u8; 2],
1848    ///     length: [u8; 2],
1849    ///     checksum: [u8; 2],
1850    /// }
1851    ///
1852    /// // These bytes encode a `PacketHeader`.
1853    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
1854    ///
1855    /// let header = PacketHeader::ref_from(bytes).unwrap();
1856    ///
1857    /// assert_eq!(header.src_port, [0, 1]);
1858    /// assert_eq!(header.dst_port, [2, 3]);
1859    /// assert_eq!(header.length, [4, 5]);
1860    /// assert_eq!(header.checksum, [6, 7]);
1861    /// ```
1862    #[inline]
1863    fn ref_from(bytes: &[u8]) -> Option<&Self>
1864    where
1865        Self: Sized,
1866    {
1867        Ref::<&[u8], Self>::new(bytes).map(Ref::into_ref)
1868    }
1869
1870    /// Interprets the prefix of the given `bytes` as a `&Self` without copying.
1871    ///
1872    /// `ref_from_prefix` returns a reference to the first `size_of::<Self>()`
1873    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or `bytes` is not
1874    /// aligned to `align_of::<Self>()`, this returns `None`.
1875    ///
1876    /// To also access the prefix bytes, use [`Ref::new_from_prefix`]. Then, use
1877    /// [`Ref::into_ref`] to get a `&Self` with the same lifetime.
1878    ///
1879    /// # Examples
1880    ///
1881    /// ```
1882    /// use zerocopy::FromBytes;
1883    /// # use zerocopy_derive::*;
1884    ///
1885    /// #[derive(FromZeroes, FromBytes)]
1886    /// #[repr(C)]
1887    /// struct PacketHeader {
1888    ///     src_port: [u8; 2],
1889    ///     dst_port: [u8; 2],
1890    ///     length: [u8; 2],
1891    ///     checksum: [u8; 2],
1892    /// }
1893    ///
1894    /// // These are more bytes than are needed to encode a `PacketHeader`.
1895    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
1896    ///
1897    /// let header = PacketHeader::ref_from_prefix(bytes).unwrap();
1898    ///
1899    /// assert_eq!(header.src_port, [0, 1]);
1900    /// assert_eq!(header.dst_port, [2, 3]);
1901    /// assert_eq!(header.length, [4, 5]);
1902    /// assert_eq!(header.checksum, [6, 7]);
1903    /// ```
1904    #[inline]
1905    fn ref_from_prefix(bytes: &[u8]) -> Option<&Self>
1906    where
1907        Self: Sized,
1908    {
1909        Ref::<&[u8], Self>::new_from_prefix(bytes).map(|(r, _)| r.into_ref())
1910    }
1911
1912    /// Interprets the suffix of the given `bytes` as a `&Self` without copying.
1913    ///
1914    /// `ref_from_suffix` returns a reference to the last `size_of::<Self>()`
1915    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or the suffix of
1916    /// `bytes` is not aligned to `align_of::<Self>()`, this returns `None`.
1917    ///
1918    /// To also access the suffix bytes, use [`Ref::new_from_suffix`]. Then, use
1919    /// [`Ref::into_ref`] to get a `&Self` with the same lifetime.
1920    ///
1921    /// # Examples
1922    ///
1923    /// ```
1924    /// use zerocopy::FromBytes;
1925    /// # use zerocopy_derive::*;
1926    ///
1927    /// #[derive(FromZeroes, FromBytes)]
1928    /// #[repr(C)]
1929    /// struct PacketTrailer {
1930    ///     frame_check_sequence: [u8; 4],
1931    /// }
1932    ///
1933    /// // These are more bytes than are needed to encode a `PacketTrailer`.
1934    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
1935    ///
1936    /// let trailer = PacketTrailer::ref_from_suffix(bytes).unwrap();
1937    ///
1938    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
1939    /// ```
1940    #[inline]
1941    fn ref_from_suffix(bytes: &[u8]) -> Option<&Self>
1942    where
1943        Self: Sized,
1944    {
1945        Ref::<&[u8], Self>::new_from_suffix(bytes).map(|(_, r)| r.into_ref())
1946    }
1947
1948    /// Interprets the given `bytes` as a `&mut Self` without copying.
1949    ///
1950    /// If `bytes.len() != size_of::<Self>()` or `bytes` is not aligned to
1951    /// `align_of::<Self>()`, this returns `None`.
1952    ///
1953    /// # Examples
1954    ///
1955    /// ```
1956    /// use zerocopy::FromBytes;
1957    /// # use zerocopy_derive::*;
1958    ///
1959    /// #[derive(AsBytes, FromZeroes, FromBytes)]
1960    /// #[repr(C)]
1961    /// struct PacketHeader {
1962    ///     src_port: [u8; 2],
1963    ///     dst_port: [u8; 2],
1964    ///     length: [u8; 2],
1965    ///     checksum: [u8; 2],
1966    /// }
1967    ///
1968    /// // These bytes encode a `PacketHeader`.
1969    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
1970    ///
1971    /// let header = PacketHeader::mut_from(bytes).unwrap();
1972    ///
1973    /// assert_eq!(header.src_port, [0, 1]);
1974    /// assert_eq!(header.dst_port, [2, 3]);
1975    /// assert_eq!(header.length, [4, 5]);
1976    /// assert_eq!(header.checksum, [6, 7]);
1977    ///
1978    /// header.checksum = [0, 0];
1979    ///
1980    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0]);
1981    /// ```
1982    #[inline]
1983    fn mut_from(bytes: &mut [u8]) -> Option<&mut Self>
1984    where
1985        Self: Sized + AsBytes,
1986    {
1987        Ref::<&mut [u8], Self>::new(bytes).map(Ref::into_mut)
1988    }
1989
1990    /// Interprets the prefix of the given `bytes` as a `&mut Self` without
1991    /// copying.
1992    ///
1993    /// `mut_from_prefix` returns a reference to the first `size_of::<Self>()`
1994    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or `bytes` is not
1995    /// aligned to `align_of::<Self>()`, this returns `None`.
1996    ///
1997    /// To also access the prefix bytes, use [`Ref::new_from_prefix`]. Then, use
1998    /// [`Ref::into_mut`] to get a `&mut Self` with the same lifetime.
1999    ///
2000    /// # Examples
2001    ///
2002    /// ```
2003    /// use zerocopy::FromBytes;
2004    /// # use zerocopy_derive::*;
2005    ///
2006    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2007    /// #[repr(C)]
2008    /// struct PacketHeader {
2009    ///     src_port: [u8; 2],
2010    ///     dst_port: [u8; 2],
2011    ///     length: [u8; 2],
2012    ///     checksum: [u8; 2],
2013    /// }
2014    ///
2015    /// // These are more bytes than are needed to encode a `PacketHeader`.
2016    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2017    ///
2018    /// let header = PacketHeader::mut_from_prefix(bytes).unwrap();
2019    ///
2020    /// assert_eq!(header.src_port, [0, 1]);
2021    /// assert_eq!(header.dst_port, [2, 3]);
2022    /// assert_eq!(header.length, [4, 5]);
2023    /// assert_eq!(header.checksum, [6, 7]);
2024    ///
2025    /// header.checksum = [0, 0];
2026    ///
2027    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 8, 9]);
2028    /// ```
2029    #[inline]
2030    fn mut_from_prefix(bytes: &mut [u8]) -> Option<&mut Self>
2031    where
2032        Self: Sized + AsBytes,
2033    {
2034        Ref::<&mut [u8], Self>::new_from_prefix(bytes).map(|(r, _)| r.into_mut())
2035    }
2036
2037    /// Interprets the suffix of the given `bytes` as a `&mut Self` without copying.
2038    ///
2039    /// `mut_from_suffix` returns a reference to the last `size_of::<Self>()`
2040    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or the suffix of
2041    /// `bytes` is not aligned to `align_of::<Self>()`, this returns `None`.
2042    ///
2043    /// To also access the suffix bytes, use [`Ref::new_from_suffix`]. Then,
2044    /// use [`Ref::into_mut`] to get a `&mut Self` with the same lifetime.
2045    ///
2046    /// # Examples
2047    ///
2048    /// ```
2049    /// use zerocopy::FromBytes;
2050    /// # use zerocopy_derive::*;
2051    ///
2052    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2053    /// #[repr(C)]
2054    /// struct PacketTrailer {
2055    ///     frame_check_sequence: [u8; 4],
2056    /// }
2057    ///
2058    /// // These are more bytes than are needed to encode a `PacketTrailer`.
2059    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2060    ///
2061    /// let trailer = PacketTrailer::mut_from_suffix(bytes).unwrap();
2062    ///
2063    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
2064    ///
2065    /// trailer.frame_check_sequence = [0, 0, 0, 0];
2066    ///
2067    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 0, 0]);
2068    /// ```
2069    #[inline]
2070    fn mut_from_suffix(bytes: &mut [u8]) -> Option<&mut Self>
2071    where
2072        Self: Sized + AsBytes,
2073    {
2074        Ref::<&mut [u8], Self>::new_from_suffix(bytes).map(|(_, r)| r.into_mut())
2075    }
2076
2077    /// Interprets the given `bytes` as a `&[Self]` without copying.
2078    ///
2079    /// If `bytes.len() % size_of::<Self>() != 0` or `bytes` is not aligned to
2080    /// `align_of::<Self>()`, this returns `None`.
2081    ///
2082    /// If you need to convert a specific number of slice elements, see
2083    /// [`slice_from_prefix`](FromBytes::slice_from_prefix) or
2084    /// [`slice_from_suffix`](FromBytes::slice_from_suffix).
2085    ///
2086    /// # Panics
2087    ///
2088    /// If `Self` is a zero-sized type.
2089    ///
2090    /// # Examples
2091    ///
2092    /// ```
2093    /// use zerocopy::FromBytes;
2094    /// # use zerocopy_derive::*;
2095    ///
2096    /// # #[derive(Debug, PartialEq, Eq)]
2097    /// #[derive(FromZeroes, FromBytes)]
2098    /// #[repr(C)]
2099    /// struct Pixel {
2100    ///     r: u8,
2101    ///     g: u8,
2102    ///     b: u8,
2103    ///     a: u8,
2104    /// }
2105    ///
2106    /// // These bytes encode two `Pixel`s.
2107    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
2108    ///
2109    /// let pixels = Pixel::slice_from(bytes).unwrap();
2110    ///
2111    /// assert_eq!(pixels, &[
2112    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2113    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2114    /// ]);
2115    /// ```
2116    #[inline]
2117    fn slice_from(bytes: &[u8]) -> Option<&[Self]>
2118    where
2119        Self: Sized,
2120    {
2121        Ref::<_, [Self]>::new_slice(bytes).map(|r| r.into_slice())
2122    }
2123
2124    /// Interprets the prefix of the given `bytes` as a `&[Self]` with length
2125    /// equal to `count` without copying.
2126    ///
2127    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2128    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2129    /// first `size_of::<T>() * count` bytes from `bytes` to construct a
2130    /// `&[Self]`, and returns the remaining bytes to the caller. It also
2131    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2132    /// If any of the length, alignment, or overflow checks fail, it returns
2133    /// `None`.
2134    ///
2135    /// # Panics
2136    ///
2137    /// If `T` is a zero-sized type.
2138    ///
2139    /// # Examples
2140    ///
2141    /// ```
2142    /// use zerocopy::FromBytes;
2143    /// # use zerocopy_derive::*;
2144    ///
2145    /// # #[derive(Debug, PartialEq, Eq)]
2146    /// #[derive(FromZeroes, FromBytes)]
2147    /// #[repr(C)]
2148    /// struct Pixel {
2149    ///     r: u8,
2150    ///     g: u8,
2151    ///     b: u8,
2152    ///     a: u8,
2153    /// }
2154    ///
2155    /// // These are more bytes than are needed to encode two `Pixel`s.
2156    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2157    ///
2158    /// let (pixels, rest) = Pixel::slice_from_prefix(bytes, 2).unwrap();
2159    ///
2160    /// assert_eq!(pixels, &[
2161    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2162    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2163    /// ]);
2164    ///
2165    /// assert_eq!(rest, &[8, 9]);
2166    /// ```
2167    #[inline]
2168    fn slice_from_prefix(bytes: &[u8], count: usize) -> Option<(&[Self], &[u8])>
2169    where
2170        Self: Sized,
2171    {
2172        Ref::<_, [Self]>::new_slice_from_prefix(bytes, count).map(|(r, b)| (r.into_slice(), b))
2173    }
2174
2175    /// Interprets the suffix of the given `bytes` as a `&[Self]` with length
2176    /// equal to `count` without copying.
2177    ///
2178    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2179    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2180    /// last `size_of::<T>() * count` bytes from `bytes` to construct a
2181    /// `&[Self]`, and returns the preceding bytes to the caller. It also
2182    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2183    /// If any of the length, alignment, or overflow checks fail, it returns
2184    /// `None`.
2185    ///
2186    /// # Panics
2187    ///
2188    /// If `T` is a zero-sized type.
2189    ///
2190    /// # Examples
2191    ///
2192    /// ```
2193    /// use zerocopy::FromBytes;
2194    /// # use zerocopy_derive::*;
2195    ///
2196    /// # #[derive(Debug, PartialEq, Eq)]
2197    /// #[derive(FromZeroes, FromBytes)]
2198    /// #[repr(C)]
2199    /// struct Pixel {
2200    ///     r: u8,
2201    ///     g: u8,
2202    ///     b: u8,
2203    ///     a: u8,
2204    /// }
2205    ///
2206    /// // These are more bytes than are needed to encode two `Pixel`s.
2207    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2208    ///
2209    /// let (rest, pixels) = Pixel::slice_from_suffix(bytes, 2).unwrap();
2210    ///
2211    /// assert_eq!(rest, &[0, 1]);
2212    ///
2213    /// assert_eq!(pixels, &[
2214    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
2215    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
2216    /// ]);
2217    /// ```
2218    #[inline]
2219    fn slice_from_suffix(bytes: &[u8], count: usize) -> Option<(&[u8], &[Self])>
2220    where
2221        Self: Sized,
2222    {
2223        Ref::<_, [Self]>::new_slice_from_suffix(bytes, count).map(|(b, r)| (b, r.into_slice()))
2224    }
2225
2226    /// Interprets the given `bytes` as a `&mut [Self]` without copying.
2227    ///
2228    /// If `bytes.len() % size_of::<T>() != 0` or `bytes` is not aligned to
2229    /// `align_of::<T>()`, this returns `None`.
2230    ///
2231    /// If you need to convert a specific number of slice elements, see
2232    /// [`mut_slice_from_prefix`](FromBytes::mut_slice_from_prefix) or
2233    /// [`mut_slice_from_suffix`](FromBytes::mut_slice_from_suffix).
2234    ///
2235    /// # Panics
2236    ///
2237    /// If `T` is a zero-sized type.
2238    ///
2239    /// # Examples
2240    ///
2241    /// ```
2242    /// use zerocopy::FromBytes;
2243    /// # use zerocopy_derive::*;
2244    ///
2245    /// # #[derive(Debug, PartialEq, Eq)]
2246    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2247    /// #[repr(C)]
2248    /// struct Pixel {
2249    ///     r: u8,
2250    ///     g: u8,
2251    ///     b: u8,
2252    ///     a: u8,
2253    /// }
2254    ///
2255    /// // These bytes encode two `Pixel`s.
2256    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
2257    ///
2258    /// let pixels = Pixel::mut_slice_from(bytes).unwrap();
2259    ///
2260    /// assert_eq!(pixels, &[
2261    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2262    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2263    /// ]);
2264    ///
2265    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2266    ///
2267    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0]);
2268    /// ```
2269    #[inline]
2270    fn mut_slice_from(bytes: &mut [u8]) -> Option<&mut [Self]>
2271    where
2272        Self: Sized + AsBytes,
2273    {
2274        Ref::<_, [Self]>::new_slice(bytes).map(|r| r.into_mut_slice())
2275    }
2276
2277    /// Interprets the prefix of the given `bytes` as a `&mut [Self]` with length
2278    /// equal to `count` without copying.
2279    ///
2280    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2281    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2282    /// first `size_of::<T>() * count` bytes from `bytes` to construct a
2283    /// `&[Self]`, and returns the remaining bytes to the caller. It also
2284    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2285    /// If any of the length, alignment, or overflow checks fail, it returns
2286    /// `None`.
2287    ///
2288    /// # Panics
2289    ///
2290    /// If `T` is a zero-sized type.
2291    ///
2292    /// # Examples
2293    ///
2294    /// ```
2295    /// use zerocopy::FromBytes;
2296    /// # use zerocopy_derive::*;
2297    ///
2298    /// # #[derive(Debug, PartialEq, Eq)]
2299    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2300    /// #[repr(C)]
2301    /// struct Pixel {
2302    ///     r: u8,
2303    ///     g: u8,
2304    ///     b: u8,
2305    ///     a: u8,
2306    /// }
2307    ///
2308    /// // These are more bytes than are needed to encode two `Pixel`s.
2309    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2310    ///
2311    /// let (pixels, rest) = Pixel::mut_slice_from_prefix(bytes, 2).unwrap();
2312    ///
2313    /// assert_eq!(pixels, &[
2314    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2315    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2316    /// ]);
2317    ///
2318    /// assert_eq!(rest, &[8, 9]);
2319    ///
2320    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2321    ///
2322    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0, 8, 9]);
2323    /// ```
2324    #[inline]
2325    fn mut_slice_from_prefix(bytes: &mut [u8], count: usize) -> Option<(&mut [Self], &mut [u8])>
2326    where
2327        Self: Sized + AsBytes,
2328    {
2329        Ref::<_, [Self]>::new_slice_from_prefix(bytes, count).map(|(r, b)| (r.into_mut_slice(), b))
2330    }
2331
2332    /// Interprets the suffix of the given `bytes` as a `&mut [Self]` with length
2333    /// equal to `count` without copying.
2334    ///
2335    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2336    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2337    /// last `size_of::<T>() * count` bytes from `bytes` to construct a
2338    /// `&[Self]`, and returns the preceding bytes to the caller. It also
2339    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2340    /// If any of the length, alignment, or overflow checks fail, it returns
2341    /// `None`.
2342    ///
2343    /// # Panics
2344    ///
2345    /// If `T` is a zero-sized type.
2346    ///
2347    /// # Examples
2348    ///
2349    /// ```
2350    /// use zerocopy::FromBytes;
2351    /// # use zerocopy_derive::*;
2352    ///
2353    /// # #[derive(Debug, PartialEq, Eq)]
2354    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2355    /// #[repr(C)]
2356    /// struct Pixel {
2357    ///     r: u8,
2358    ///     g: u8,
2359    ///     b: u8,
2360    ///     a: u8,
2361    /// }
2362    ///
2363    /// // These are more bytes than are needed to encode two `Pixel`s.
2364    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2365    ///
2366    /// let (rest, pixels) = Pixel::mut_slice_from_suffix(bytes, 2).unwrap();
2367    ///
2368    /// assert_eq!(rest, &[0, 1]);
2369    ///
2370    /// assert_eq!(pixels, &[
2371    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
2372    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
2373    /// ]);
2374    ///
2375    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2376    ///
2377    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 0, 0]);
2378    /// ```
2379    #[inline]
2380    fn mut_slice_from_suffix(bytes: &mut [u8], count: usize) -> Option<(&mut [u8], &mut [Self])>
2381    where
2382        Self: Sized + AsBytes,
2383    {
2384        Ref::<_, [Self]>::new_slice_from_suffix(bytes, count).map(|(b, r)| (b, r.into_mut_slice()))
2385    }
2386
2387    /// Reads a copy of `Self` from `bytes`.
2388    ///
2389    /// If `bytes.len() != size_of::<Self>()`, `read_from` returns `None`.
2390    ///
2391    /// # Examples
2392    ///
2393    /// ```
2394    /// use zerocopy::FromBytes;
2395    /// # use zerocopy_derive::*;
2396    ///
2397    /// #[derive(FromZeroes, FromBytes)]
2398    /// #[repr(C)]
2399    /// struct PacketHeader {
2400    ///     src_port: [u8; 2],
2401    ///     dst_port: [u8; 2],
2402    ///     length: [u8; 2],
2403    ///     checksum: [u8; 2],
2404    /// }
2405    ///
2406    /// // These bytes encode a `PacketHeader`.
2407    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
2408    ///
2409    /// let header = PacketHeader::read_from(bytes).unwrap();
2410    ///
2411    /// assert_eq!(header.src_port, [0, 1]);
2412    /// assert_eq!(header.dst_port, [2, 3]);
2413    /// assert_eq!(header.length, [4, 5]);
2414    /// assert_eq!(header.checksum, [6, 7]);
2415    /// ```
2416    #[inline]
2417    fn read_from(bytes: &[u8]) -> Option<Self>
2418    where
2419        Self: Sized,
2420    {
2421        Ref::<_, Unalign<Self>>::new_unaligned(bytes).map(|r| r.read().into_inner())
2422    }
2423
2424    /// Reads a copy of `Self` from the prefix of `bytes`.
2425    ///
2426    /// `read_from_prefix` reads a `Self` from the first `size_of::<Self>()`
2427    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
2428    /// `None`.
2429    ///
2430    /// # Examples
2431    ///
2432    /// ```
2433    /// use zerocopy::FromBytes;
2434    /// # use zerocopy_derive::*;
2435    ///
2436    /// #[derive(FromZeroes, FromBytes)]
2437    /// #[repr(C)]
2438    /// struct PacketHeader {
2439    ///     src_port: [u8; 2],
2440    ///     dst_port: [u8; 2],
2441    ///     length: [u8; 2],
2442    ///     checksum: [u8; 2],
2443    /// }
2444    ///
2445    /// // These are more bytes than are needed to encode a `PacketHeader`.
2446    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2447    ///
2448    /// let header = PacketHeader::read_from_prefix(bytes).unwrap();
2449    ///
2450    /// assert_eq!(header.src_port, [0, 1]);
2451    /// assert_eq!(header.dst_port, [2, 3]);
2452    /// assert_eq!(header.length, [4, 5]);
2453    /// assert_eq!(header.checksum, [6, 7]);
2454    /// ```
2455    #[inline]
2456    fn read_from_prefix(bytes: &[u8]) -> Option<Self>
2457    where
2458        Self: Sized,
2459    {
2460        Ref::<_, Unalign<Self>>::new_unaligned_from_prefix(bytes)
2461            .map(|(r, _)| r.read().into_inner())
2462    }
2463
2464    /// Reads a copy of `Self` from the suffix of `bytes`.
2465    ///
2466    /// `read_from_suffix` reads a `Self` from the last `size_of::<Self>()`
2467    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
2468    /// `None`.
2469    ///
2470    /// # Examples
2471    ///
2472    /// ```
2473    /// use zerocopy::FromBytes;
2474    /// # use zerocopy_derive::*;
2475    ///
2476    /// #[derive(FromZeroes, FromBytes)]
2477    /// #[repr(C)]
2478    /// struct PacketTrailer {
2479    ///     frame_check_sequence: [u8; 4],
2480    /// }
2481    ///
2482    /// // These are more bytes than are needed to encode a `PacketTrailer`.
2483    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2484    ///
2485    /// let trailer = PacketTrailer::read_from_suffix(bytes).unwrap();
2486    ///
2487    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
2488    /// ```
2489    #[inline]
2490    fn read_from_suffix(bytes: &[u8]) -> Option<Self>
2491    where
2492        Self: Sized,
2493    {
2494        Ref::<_, Unalign<Self>>::new_unaligned_from_suffix(bytes)
2495            .map(|(_, r)| r.read().into_inner())
2496    }
2497}
2498
2499/// Analyzes whether a type is [`AsBytes`].
2500///
2501/// This derive analyzes, at compile time, whether the annotated type satisfies
2502/// the [safety conditions] of `AsBytes` and implements `AsBytes` if it is
2503/// sound to do so. This derive can be applied to structs, enums, and unions;
2504/// e.g.:
2505///
2506/// ```
2507/// # use zerocopy_derive::{AsBytes};
2508/// #[derive(AsBytes)]
2509/// #[repr(C)]
2510/// struct MyStruct {
2511/// # /*
2512///     ...
2513/// # */
2514/// }
2515///
2516/// #[derive(AsBytes)]
2517/// #[repr(u8)]
2518/// enum MyEnum {
2519/// #   Variant,
2520/// # /*
2521///     ...
2522/// # */
2523/// }
2524///
2525/// #[derive(AsBytes)]
2526/// #[repr(C)]
2527/// union MyUnion {
2528/// #   variant: u8,
2529/// # /*
2530///     ...
2531/// # */
2532/// }
2533/// ```
2534///
2535/// [safety conditions]: trait@AsBytes#safety
2536///
2537/// # Error Messages
2538///
2539/// Due to the way that the custom derive for `AsBytes` is implemented, you may
2540/// get an error like this:
2541///
2542/// ```text
2543/// error[E0277]: the trait bound `HasPadding<Foo, true>: ShouldBe<false>` is not satisfied
2544///   --> lib.rs:23:10
2545///    |
2546///  1 | #[derive(AsBytes)]
2547///    |          ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<Foo, true>`
2548///    |
2549///    = help: the trait `ShouldBe<VALUE>` is implemented for `HasPadding<T, VALUE>`
2550/// ```
2551///
2552/// This error indicates that the type being annotated has padding bytes, which
2553/// is illegal for `AsBytes` types. Consider reducing the alignment of some
2554/// fields by using types in the [`byteorder`] module, adding explicit struct
2555/// fields where those padding bytes would be, or using `#[repr(packed)]`. See
2556/// the Rust Reference's page on [type layout] for more information
2557/// about type layout and padding.
2558///
2559/// [type layout]: https://doc.rust-lang.org/reference/type-layout.html
2560///
2561/// # Analysis
2562///
2563/// *This section describes, roughly, the analysis performed by this derive to
2564/// determine whether it is sound to implement `AsBytes` for a given type.
2565/// Unless you are modifying the implementation of this derive, or attempting to
2566/// manually implement `AsBytes` for a type yourself, you don't need to read
2567/// this section.*
2568///
2569/// If a type has the following properties, then this derive can implement
2570/// `AsBytes` for that type:
2571///
2572/// - If the type is a struct:
2573///   - It must have a defined representation (`repr(C)`, `repr(transparent)`,
2574///     or `repr(packed)`).
2575///   - All of its fields must be `AsBytes`.
2576///   - Its layout must have no padding. This is always true for
2577///     `repr(transparent)` and `repr(packed)`. For `repr(C)`, see the layout
2578///     algorithm described in the [Rust Reference].
2579/// - If the type is an enum:
2580///   - It must be a C-like enum (meaning that all variants have no fields).
2581///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
2582///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
2583/// - The type must not contain any [`UnsafeCell`]s (this is required in order
2584///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
2585///   memory). The type may contain references or pointers to `UnsafeCell`s so
2586///   long as those values can themselves be initialized from zeroes (`AsBytes`
2587///   is not currently implemented for, e.g., `Option<&UnsafeCell<_>>`, but it
2588///   could be one day).
2589///
2590/// [`UnsafeCell`]: core::cell::UnsafeCell
2591///
2592/// This analysis is subject to change. Unsafe code may *only* rely on the
2593/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
2594/// implementation details of this derive.
2595///
2596/// [Rust Reference]: https://doc.rust-lang.org/reference/type-layout.html
2597#[cfg(any(feature = "derive", test))]
2598#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
2599pub use zerocopy_derive::AsBytes;
2600
2601/// Types that can be viewed as an immutable slice of initialized bytes.
2602///
2603/// Any `AsBytes` type can be viewed as a slice of initialized bytes of the same
2604/// size. This is useful for efficiently serializing structured data as raw
2605/// bytes.
2606///
2607/// # Implementation
2608///
2609/// **Do not implement this trait yourself!** Instead, use
2610/// [`#[derive(AsBytes)]`][derive] (requires the `derive` Cargo feature); e.g.:
2611///
2612/// ```
2613/// # use zerocopy_derive::AsBytes;
2614/// #[derive(AsBytes)]
2615/// #[repr(C)]
2616/// struct MyStruct {
2617/// # /*
2618///     ...
2619/// # */
2620/// }
2621///
2622/// #[derive(AsBytes)]
2623/// #[repr(u8)]
2624/// enum MyEnum {
2625/// #   Variant0,
2626/// # /*
2627///     ...
2628/// # */
2629/// }
2630///
2631/// #[derive(AsBytes)]
2632/// #[repr(C)]
2633/// union MyUnion {
2634/// #   variant: u8,
2635/// # /*
2636///     ...
2637/// # */
2638/// }
2639/// ```
2640///
2641/// This derive performs a sophisticated, compile-time safety analysis to
2642/// determine whether a type is `AsBytes`. See the [derive
2643/// documentation][derive] for guidance on how to interpret error messages
2644/// produced by the derive's analysis.
2645///
2646/// # Safety
2647///
2648/// *This section describes what is required in order for `T: AsBytes`, and
2649/// what unsafe code may assume of such types. If you don't plan on implementing
2650/// `AsBytes` manually, and you don't plan on writing unsafe code that
2651/// operates on `AsBytes` types, then you don't need to read this section.*
2652///
2653/// If `T: AsBytes`, then unsafe code may assume that:
2654/// - It is sound to treat any `t: T` as an immutable `[u8]` of length
2655///   `size_of_val(t)`.
2656/// - Given `t: &T`, it is sound to construct a `b: &[u8]` where `b.len() ==
2657///   size_of_val(t)` at the same address as `t`, and it is sound for both `b`
2658///   and `t` to be live at the same time.
2659///
2660/// If a type is marked as `AsBytes` which violates this contract, it may cause
2661/// undefined behavior.
2662///
2663/// `#[derive(AsBytes)]` only permits [types which satisfy these
2664/// requirements][derive-analysis].
2665///
2666#[cfg_attr(
2667    feature = "derive",
2668    doc = "[derive]: zerocopy_derive::AsBytes",
2669    doc = "[derive-analysis]: zerocopy_derive::AsBytes#analysis"
2670)]
2671#[cfg_attr(
2672    not(feature = "derive"),
2673    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.AsBytes.html"),
2674    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.AsBytes.html#analysis"),
2675)]
2676pub unsafe trait AsBytes {
2677    // The `Self: Sized` bound makes it so that this function doesn't prevent
2678    // `AsBytes` from being object safe. Note that other `AsBytes` methods
2679    // prevent object safety, but those provide a benefit in exchange for object
2680    // safety. If at some point we remove those methods, change their type
2681    // signatures, or move them out of this trait so that `AsBytes` is object
2682    // safe again, it's important that this function not prevent object safety.
2683    #[doc(hidden)]
2684    fn only_derive_is_allowed_to_implement_this_trait()
2685    where
2686        Self: Sized;
2687
2688    /// Gets the bytes of this value.
2689    ///
2690    /// `as_bytes` provides access to the bytes of this value as an immutable
2691    /// byte slice.
2692    ///
2693    /// # Examples
2694    ///
2695    /// ```
2696    /// use zerocopy::AsBytes;
2697    /// # use zerocopy_derive::*;
2698    ///
2699    /// #[derive(AsBytes)]
2700    /// #[repr(C)]
2701    /// struct PacketHeader {
2702    ///     src_port: [u8; 2],
2703    ///     dst_port: [u8; 2],
2704    ///     length: [u8; 2],
2705    ///     checksum: [u8; 2],
2706    /// }
2707    ///
2708    /// let header = PacketHeader {
2709    ///     src_port: [0, 1],
2710    ///     dst_port: [2, 3],
2711    ///     length: [4, 5],
2712    ///     checksum: [6, 7],
2713    /// };
2714    ///
2715    /// let bytes = header.as_bytes();
2716    ///
2717    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2718    /// ```
2719    #[inline(always)]
2720    fn as_bytes(&self) -> &[u8] {
2721        // Note that this method does not have a `Self: Sized` bound;
2722        // `size_of_val` works for unsized values too.
2723        let len = mem::size_of_val(self);
2724        let slf: *const Self = self;
2725
2726        // SAFETY:
2727        // - `slf.cast::<u8>()` is valid for reads for `len *
2728        //   mem::size_of::<u8>()` many bytes because...
2729        //   - `slf` is the same pointer as `self`, and `self` is a reference
2730        //     which points to an object whose size is `len`. Thus...
2731        //     - The entire region of `len` bytes starting at `slf` is contained
2732        //       within a single allocation.
2733        //     - `slf` is non-null.
2734        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
2735        // - `Self: AsBytes` ensures that all of the bytes of `slf` are
2736        //   initialized.
2737        // - Since `slf` is derived from `self`, and `self` is an immutable
2738        //   reference, the only other references to this memory region that
2739        //   could exist are other immutable references, and those don't allow
2740        //   mutation. `AsBytes` prohibits types which contain `UnsafeCell`s,
2741        //   which are the only types for which this rule wouldn't be sufficient.
2742        // - The total size of the resulting slice is no larger than
2743        //   `isize::MAX` because no allocation produced by safe code can be
2744        //   larger than `isize::MAX`.
2745        //
2746        // TODO(#429): Add references to docs and quotes.
2747        unsafe { slice::from_raw_parts(slf.cast::<u8>(), len) }
2748    }
2749
2750    /// Gets the bytes of this value mutably.
2751    ///
2752    /// `as_bytes_mut` provides access to the bytes of this value as a mutable
2753    /// byte slice.
2754    ///
2755    /// # Examples
2756    ///
2757    /// ```
2758    /// use zerocopy::AsBytes;
2759    /// # use zerocopy_derive::*;
2760    ///
2761    /// # #[derive(Eq, PartialEq, Debug)]
2762    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2763    /// #[repr(C)]
2764    /// struct PacketHeader {
2765    ///     src_port: [u8; 2],
2766    ///     dst_port: [u8; 2],
2767    ///     length: [u8; 2],
2768    ///     checksum: [u8; 2],
2769    /// }
2770    ///
2771    /// let mut header = PacketHeader {
2772    ///     src_port: [0, 1],
2773    ///     dst_port: [2, 3],
2774    ///     length: [4, 5],
2775    ///     checksum: [6, 7],
2776    /// };
2777    ///
2778    /// let bytes = header.as_bytes_mut();
2779    ///
2780    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2781    ///
2782    /// bytes.reverse();
2783    ///
2784    /// assert_eq!(header, PacketHeader {
2785    ///     src_port: [7, 6],
2786    ///     dst_port: [5, 4],
2787    ///     length: [3, 2],
2788    ///     checksum: [1, 0],
2789    /// });
2790    /// ```
2791    #[inline(always)]
2792    fn as_bytes_mut(&mut self) -> &mut [u8]
2793    where
2794        Self: FromBytes,
2795    {
2796        // Note that this method does not have a `Self: Sized` bound;
2797        // `size_of_val` works for unsized values too.
2798        let len = mem::size_of_val(self);
2799        let slf: *mut Self = self;
2800
2801        // SAFETY:
2802        // - `slf.cast::<u8>()` is valid for reads and writes for `len *
2803        //   mem::size_of::<u8>()` many bytes because...
2804        //   - `slf` is the same pointer as `self`, and `self` is a reference
2805        //     which points to an object whose size is `len`. Thus...
2806        //     - The entire region of `len` bytes starting at `slf` is contained
2807        //       within a single allocation.
2808        //     - `slf` is non-null.
2809        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
2810        // - `Self: AsBytes` ensures that all of the bytes of `slf` are
2811        //   initialized.
2812        // - `Self: FromBytes` ensures that no write to this memory region
2813        //   could result in it containing an invalid `Self`.
2814        // - Since `slf` is derived from `self`, and `self` is a mutable
2815        //   reference, no other references to this memory region can exist.
2816        // - The total size of the resulting slice is no larger than
2817        //   `isize::MAX` because no allocation produced by safe code can be
2818        //   larger than `isize::MAX`.
2819        //
2820        // TODO(#429): Add references to docs and quotes.
2821        unsafe { slice::from_raw_parts_mut(slf.cast::<u8>(), len) }
2822    }
2823
2824    /// Writes a copy of `self` to `bytes`.
2825    ///
2826    /// If `bytes.len() != size_of_val(self)`, `write_to` returns `None`.
2827    ///
2828    /// # Examples
2829    ///
2830    /// ```
2831    /// use zerocopy::AsBytes;
2832    /// # use zerocopy_derive::*;
2833    ///
2834    /// #[derive(AsBytes)]
2835    /// #[repr(C)]
2836    /// struct PacketHeader {
2837    ///     src_port: [u8; 2],
2838    ///     dst_port: [u8; 2],
2839    ///     length: [u8; 2],
2840    ///     checksum: [u8; 2],
2841    /// }
2842    ///
2843    /// let header = PacketHeader {
2844    ///     src_port: [0, 1],
2845    ///     dst_port: [2, 3],
2846    ///     length: [4, 5],
2847    ///     checksum: [6, 7],
2848    /// };
2849    ///
2850    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0];
2851    ///
2852    /// header.write_to(&mut bytes[..]);
2853    ///
2854    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2855    /// ```
2856    ///
2857    /// If too many or too few target bytes are provided, `write_to` returns
2858    /// `None` and leaves the target bytes unmodified:
2859    ///
2860    /// ```
2861    /// # use zerocopy::AsBytes;
2862    /// # let header = u128::MAX;
2863    /// let mut excessive_bytes = &mut [0u8; 128][..];
2864    ///
2865    /// let write_result = header.write_to(excessive_bytes);
2866    ///
2867    /// assert!(write_result.is_none());
2868    /// assert_eq!(excessive_bytes, [0u8; 128]);
2869    /// ```
2870    #[inline]
2871    fn write_to(&self, bytes: &mut [u8]) -> Option<()> {
2872        if bytes.len() != mem::size_of_val(self) {
2873            return None;
2874        }
2875
2876        bytes.copy_from_slice(self.as_bytes());
2877        Some(())
2878    }
2879
2880    /// Writes a copy of `self` to the prefix of `bytes`.
2881    ///
2882    /// `write_to_prefix` writes `self` to the first `size_of_val(self)` bytes
2883    /// of `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
2884    ///
2885    /// # Examples
2886    ///
2887    /// ```
2888    /// use zerocopy::AsBytes;
2889    /// # use zerocopy_derive::*;
2890    ///
2891    /// #[derive(AsBytes)]
2892    /// #[repr(C)]
2893    /// struct PacketHeader {
2894    ///     src_port: [u8; 2],
2895    ///     dst_port: [u8; 2],
2896    ///     length: [u8; 2],
2897    ///     checksum: [u8; 2],
2898    /// }
2899    ///
2900    /// let header = PacketHeader {
2901    ///     src_port: [0, 1],
2902    ///     dst_port: [2, 3],
2903    ///     length: [4, 5],
2904    ///     checksum: [6, 7],
2905    /// };
2906    ///
2907    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2908    ///
2909    /// header.write_to_prefix(&mut bytes[..]);
2910    ///
2911    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7, 0, 0]);
2912    /// ```
2913    ///
2914    /// If insufficient target bytes are provided, `write_to_prefix` returns
2915    /// `None` and leaves the target bytes unmodified:
2916    ///
2917    /// ```
2918    /// # use zerocopy::AsBytes;
2919    /// # let header = u128::MAX;
2920    /// let mut insufficent_bytes = &mut [0, 0][..];
2921    ///
2922    /// let write_result = header.write_to_suffix(insufficent_bytes);
2923    ///
2924    /// assert!(write_result.is_none());
2925    /// assert_eq!(insufficent_bytes, [0, 0]);
2926    /// ```
2927    #[inline]
2928    fn write_to_prefix(&self, bytes: &mut [u8]) -> Option<()> {
2929        let size = mem::size_of_val(self);
2930        bytes.get_mut(..size)?.copy_from_slice(self.as_bytes());
2931        Some(())
2932    }
2933
2934    /// Writes a copy of `self` to the suffix of `bytes`.
2935    ///
2936    /// `write_to_suffix` writes `self` to the last `size_of_val(self)` bytes of
2937    /// `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
2938    ///
2939    /// # Examples
2940    ///
2941    /// ```
2942    /// use zerocopy::AsBytes;
2943    /// # use zerocopy_derive::*;
2944    ///
2945    /// #[derive(AsBytes)]
2946    /// #[repr(C)]
2947    /// struct PacketHeader {
2948    ///     src_port: [u8; 2],
2949    ///     dst_port: [u8; 2],
2950    ///     length: [u8; 2],
2951    ///     checksum: [u8; 2],
2952    /// }
2953    ///
2954    /// let header = PacketHeader {
2955    ///     src_port: [0, 1],
2956    ///     dst_port: [2, 3],
2957    ///     length: [4, 5],
2958    ///     checksum: [6, 7],
2959    /// };
2960    ///
2961    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2962    ///
2963    /// header.write_to_suffix(&mut bytes[..]);
2964    ///
2965    /// assert_eq!(bytes, [0, 0, 0, 1, 2, 3, 4, 5, 6, 7]);
2966    ///
2967    /// let mut insufficent_bytes = &mut [0, 0][..];
2968    ///
2969    /// let write_result = header.write_to_suffix(insufficent_bytes);
2970    ///
2971    /// assert!(write_result.is_none());
2972    /// assert_eq!(insufficent_bytes, [0, 0]);
2973    /// ```
2974    ///
2975    /// If insufficient target bytes are provided, `write_to_suffix` returns
2976    /// `None` and leaves the target bytes unmodified:
2977    ///
2978    /// ```
2979    /// # use zerocopy::AsBytes;
2980    /// # let header = u128::MAX;
2981    /// let mut insufficent_bytes = &mut [0, 0][..];
2982    ///
2983    /// let write_result = header.write_to_suffix(insufficent_bytes);
2984    ///
2985    /// assert!(write_result.is_none());
2986    /// assert_eq!(insufficent_bytes, [0, 0]);
2987    /// ```
2988    #[inline]
2989    fn write_to_suffix(&self, bytes: &mut [u8]) -> Option<()> {
2990        let start = bytes.len().checked_sub(mem::size_of_val(self))?;
2991        bytes
2992            .get_mut(start..)
2993            .expect("`start` should be in-bounds of `bytes`")
2994            .copy_from_slice(self.as_bytes());
2995        Some(())
2996    }
2997}
2998
2999/// Types with no alignment requirement.
3000///
3001/// WARNING: Do not implement this trait yourself! Instead, use
3002/// `#[derive(Unaligned)]` (requires the `derive` Cargo feature).
3003///
3004/// If `T: Unaligned`, then `align_of::<T>() == 1`.
3005///
3006/// # Safety
3007///
3008/// *This section describes what is required in order for `T: Unaligned`, and
3009/// what unsafe code may assume of such types. `#[derive(Unaligned)]` only
3010/// permits types which satisfy these requirements. If you don't plan on
3011/// implementing `Unaligned` manually, and you don't plan on writing unsafe code
3012/// that operates on `Unaligned` types, then you don't need to read this
3013/// section.*
3014///
3015/// If `T: Unaligned`, then unsafe code may assume that it is sound to produce a
3016/// reference to `T` at any memory location regardless of alignment. If a type
3017/// is marked as `Unaligned` which violates this contract, it may cause
3018/// undefined behavior.
3019pub unsafe trait Unaligned {
3020    // The `Self: Sized` bound makes it so that `Unaligned` is still object
3021    // safe.
3022    #[doc(hidden)]
3023    fn only_derive_is_allowed_to_implement_this_trait()
3024    where
3025        Self: Sized;
3026}
3027
3028safety_comment! {
3029    /// SAFETY:
3030    /// Per the reference [1], "the unit tuple (`()`) ... is guaranteed as a
3031    /// zero-sized type to have a size of 0 and an alignment of 1."
3032    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: There
3033    ///   is only one possible sequence of 0 bytes, and `()` is inhabited.
3034    /// - `AsBytes`: Since `()` has size 0, it contains no padding bytes.
3035    /// - `Unaligned`: `()` has alignment 1.
3036    ///
3037    /// [1] https://doc.rust-lang.org/reference/type-layout.html#tuple-layout
3038    unsafe_impl!((): TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3039    assert_unaligned!(());
3040}
3041
3042safety_comment! {
3043    /// SAFETY:
3044    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: all bit
3045    ///   patterns are valid for numeric types [1]
3046    /// - `AsBytes`: numeric types have no padding bytes [1]
3047    /// - `Unaligned` (`u8` and `i8` only): The reference [2] specifies the size
3048    ///   of `u8` and `i8` as 1 byte. We also know that:
3049    ///   - Alignment is >= 1 [3]
3050    ///   - Size is an integer multiple of alignment [4]
3051    ///   - The only value >= 1 for which 1 is an integer multiple is 1
3052    ///   Therefore, the only possible alignment for `u8` and `i8` is 1.
3053    ///
3054    /// [1] Per https://doc.rust-lang.org/beta/reference/types/numeric.html#bit-validity:
3055    ///
3056    ///     For every numeric type, `T`, the bit validity of `T` is equivalent to
3057    ///     the bit validity of `[u8; size_of::<T>()]`. An uninitialized byte is
3058    ///     not a valid `u8`.
3059    ///
3060    /// TODO(https://github.com/rust-lang/reference/pull/1392): Once this text
3061    /// is available on the Stable docs, cite those instead.
3062    ///
3063    /// [2] https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout
3064    ///
3065    /// [3] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3066    ///
3067    ///     Alignment is measured in bytes, and must be at least 1.
3068    ///
3069    /// [4] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3070    ///
3071    ///     The size of a value is always a multiple of its alignment.
3072    ///
3073    /// TODO(#278): Once we've updated the trait docs to refer to `u8`s rather
3074    /// than bits or bytes, update this comment, especially the reference to
3075    /// [1].
3076    unsafe_impl!(u8: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3077    unsafe_impl!(i8: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3078    assert_unaligned!(u8, i8);
3079    unsafe_impl!(u16: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3080    unsafe_impl!(i16: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3081    unsafe_impl!(u32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3082    unsafe_impl!(i32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3083    unsafe_impl!(u64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3084    unsafe_impl!(i64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3085    unsafe_impl!(u128: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3086    unsafe_impl!(i128: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3087    unsafe_impl!(usize: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3088    unsafe_impl!(isize: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3089    unsafe_impl!(f32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3090    unsafe_impl!(f64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3091}
3092
3093safety_comment! {
3094    /// SAFETY:
3095    /// - `FromZeroes`: Valid since "[t]he value false has the bit pattern
3096    ///   0x00" [1].
3097    /// - `AsBytes`: Since "the boolean type has a size and alignment of 1 each"
3098    ///   and "The value false has the bit pattern 0x00 and the value true has
3099    ///   the bit pattern 0x01" [1]. Thus, the only byte of the bool is always
3100    ///   initialized.
3101    /// - `Unaligned`: Per the reference [1], "[a]n object with the boolean type
3102    ///   has a size and alignment of 1 each."
3103    ///
3104    /// [1] https://doc.rust-lang.org/reference/types/boolean.html
3105    unsafe_impl!(bool: FromZeroes, AsBytes, Unaligned);
3106    assert_unaligned!(bool);
3107    /// SAFETY:
3108    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3109    ///   closure:
3110    ///   - Given `t: *mut bool` and `let r = *mut u8`, `r` refers to an object
3111    ///     of the same size as that referred to by `t`. This is true because
3112    ///     `bool` and `u8` have the same size (1 byte) [1].
3113    ///   - Since the closure takes a `&u8` argument, given a `Ptr<'a, bool>`
3114    ///     which satisfies the preconditions of
3115    ///     `TryFromBytes::<bool>::is_bit_valid`, it must be guaranteed that the
3116    ///     memory referenced by that `Ptr` always contains a valid `u8`. Since
3117    ///     `bool`'s single byte is always initialized, `is_bit_valid`'s
3118    ///     precondition requires that the same is true of its argument. Since
3119    ///     `u8`'s only bit validity invariant is that its single byte must be
3120    ///     initialized, this memory is guaranteed to contain a valid `u8`.
3121    ///   - The alignment of `bool` is equal to the alignment of `u8`. [1] [2]
3122    ///   - The impl must only return `true` for its argument if the original
3123    ///     `Ptr<bool>` refers to a valid `bool`. We only return true if the
3124    ///     `u8` value is 0 or 1, and both of these are valid values for `bool`.
3125    ///     [3]
3126    ///
3127    /// [1] Per https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout:
3128    ///
3129    ///   The size of most primitives is given in this table.
3130    ///
3131    ///   | Type      | `size_of::<Type>() ` |
3132    ///   |-----------|----------------------|
3133    ///   | `bool`    | 1                    |
3134    ///   | `u8`/`i8` | 1                    |
3135    ///
3136    /// [2] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3137    ///
3138    ///   The size of a value is always a multiple of its alignment.
3139    ///
3140    /// [3] Per https://doc.rust-lang.org/reference/types/boolean.html:
3141    ///
3142    ///   The value false has the bit pattern 0x00 and the value true has the
3143    ///   bit pattern 0x01.
3144    unsafe_impl!(bool: TryFromBytes; |byte: &u8| *byte < 2);
3145}
3146safety_comment! {
3147    /// SAFETY:
3148    /// - `FromZeroes`: Per reference [1], "[a] value of type char is a Unicode
3149    ///   scalar value (i.e. a code point that is not a surrogate), represented
3150    ///   as a 32-bit unsigned word in the 0x0000 to 0xD7FF or 0xE000 to
3151    ///   0x10FFFF range" which contains 0x0000.
3152    /// - `AsBytes`: `char` is per reference [1] "represented as a 32-bit
3153    ///   unsigned word" (`u32`) which is `AsBytes`. Note that unlike `u32`, not
3154    ///   all bit patterns are valid for `char`.
3155    ///
3156    /// [1] https://doc.rust-lang.org/reference/types/textual.html
3157    unsafe_impl!(char: FromZeroes, AsBytes);
3158    /// SAFETY:
3159    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3160    ///   closure:
3161    ///   - Given `t: *mut char` and `let r = *mut u32`, `r` refers to an object
3162    ///     of the same size as that referred to by `t`. This is true because
3163    ///     `char` and `u32` have the same size [1].
3164    ///   - Since the closure takes a `&u32` argument, given a `Ptr<'a, char>`
3165    ///     which satisfies the preconditions of
3166    ///     `TryFromBytes::<char>::is_bit_valid`, it must be guaranteed that the
3167    ///     memory referenced by that `Ptr` always contains a valid `u32`. Since
3168    ///     `char`'s bytes are always initialized [2], `is_bit_valid`'s
3169    ///     precondition requires that the same is true of its argument. Since
3170    ///     `u32`'s only bit validity invariant is that its bytes must be
3171    ///     initialized, this memory is guaranteed to contain a valid `u32`.
3172    ///   - The alignment of `char` is equal to the alignment of `u32`. [1]
3173    ///   - The impl must only return `true` for its argument if the original
3174    ///     `Ptr<char>` refers to a valid `char`. `char::from_u32` guarantees
3175    ///     that it returns `None` if its input is not a valid `char`. [3]
3176    ///
3177    /// [1] Per https://doc.rust-lang.org/nightly/reference/types/textual.html#layout-and-bit-validity:
3178    ///
3179    ///   `char` is guaranteed to have the same size and alignment as `u32` on
3180    ///   all platforms.
3181    ///
3182    /// [2] Per https://doc.rust-lang.org/core/primitive.char.html#method.from_u32:
3183    ///
3184    ///   Every byte of a `char` is guaranteed to be initialized.
3185    ///
3186    /// [3] Per https://doc.rust-lang.org/core/primitive.char.html#method.from_u32:
3187    ///
3188    ///   `from_u32()` will return `None` if the input is not a valid value for
3189    ///   a `char`.
3190    unsafe_impl!(char: TryFromBytes; |candidate: &u32| char::from_u32(*candidate).is_some());
3191}
3192safety_comment! {
3193    /// SAFETY:
3194    /// - `FromZeroes`, `AsBytes`, `Unaligned`: Per the reference [1], `str`
3195    ///   has the same layout as `[u8]`, and `[u8]` is `FromZeroes`, `AsBytes`,
3196    ///   and `Unaligned`.
3197    ///
3198    /// Note that we don't `assert_unaligned!(str)` because `assert_unaligned!`
3199    /// uses `align_of`, which only works for `Sized` types.
3200    ///
3201    /// TODO(#429): Add quotes from documentation.
3202    ///
3203    /// [1] https://doc.rust-lang.org/reference/type-layout.html#str-layout
3204    unsafe_impl!(str: FromZeroes, AsBytes, Unaligned);
3205    /// SAFETY:
3206    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3207    ///   closure:
3208    ///   - Given `t: *mut str` and `let r = *mut [u8]`, `r` refers to an object
3209    ///     of the same size as that referred to by `t`. This is true because
3210    ///     `str` and `[u8]` have the same representation. [1]
3211    ///   - Since the closure takes a `&[u8]` argument, given a `Ptr<'a, str>`
3212    ///     which satisfies the preconditions of
3213    ///     `TryFromBytes::<str>::is_bit_valid`, it must be guaranteed that the
3214    ///     memory referenced by that `Ptr` always contains a valid `[u8]`.
3215    ///     Since `str`'s bytes are always initialized [1], `is_bit_valid`'s
3216    ///     precondition requires that the same is true of its argument. Since
3217    ///     `[u8]`'s only bit validity invariant is that its bytes must be
3218    ///     initialized, this memory is guaranteed to contain a valid `[u8]`.
3219    ///   - The alignment of `str` is equal to the alignment of `[u8]`. [1]
3220    ///   - The impl must only return `true` for its argument if the original
3221    ///     `Ptr<str>` refers to a valid `str`. `str::from_utf8` guarantees that
3222    ///     it returns `Err` if its input is not a valid `str`. [2]
3223    ///
3224    /// [1] Per https://doc.rust-lang.org/reference/types/textual.html:
3225    ///
3226    ///   A value of type `str` is represented the same was as `[u8]`.
3227    ///
3228    /// [2] Per https://doc.rust-lang.org/core/str/fn.from_utf8.html#errors:
3229    ///
3230    ///   Returns `Err` if the slice is not UTF-8.
3231    unsafe_impl!(str: TryFromBytes; |candidate: &[u8]| core::str::from_utf8(candidate).is_ok());
3232}
3233
3234safety_comment! {
3235    // `NonZeroXxx` is `AsBytes`, but not `FromZeroes` or `FromBytes`.
3236    //
3237    /// SAFETY:
3238    /// - `AsBytes`: `NonZeroXxx` has the same layout as its associated
3239    ///    primitive. Since it is the same size, this guarantees it has no
3240    ///    padding - integers have no padding, and there's no room for padding
3241    ///    if it can represent all of the same values except 0.
3242    /// - `Unaligned`: `NonZeroU8` and `NonZeroI8` document that
3243    ///   `Option<NonZeroU8>` and `Option<NonZeroI8>` both have size 1. [1] [2]
3244    ///   This is worded in a way that makes it unclear whether it's meant as a
3245    ///   guarantee, but given the purpose of those types, it's virtually
3246    ///   unthinkable that that would ever change. `Option` cannot be smaller
3247    ///   than its contained type, which implies that, and `NonZeroX8` are of
3248    ///   size 1 or 0. `NonZeroX8` can represent multiple states, so they cannot
3249    ///   be 0 bytes, which means that they must be 1 byte. The only valid
3250    ///   alignment for a 1-byte type is 1.
3251    ///
3252    /// TODO(#429): Add quotes from documentation.
3253    ///
3254    /// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
3255    /// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
3256    /// TODO(https://github.com/rust-lang/rust/pull/104082): Cite documentation
3257    /// that layout is the same as primitive layout.
3258    unsafe_impl!(NonZeroU8: AsBytes, Unaligned);
3259    unsafe_impl!(NonZeroI8: AsBytes, Unaligned);
3260    assert_unaligned!(NonZeroU8, NonZeroI8);
3261    unsafe_impl!(NonZeroU16: AsBytes);
3262    unsafe_impl!(NonZeroI16: AsBytes);
3263    unsafe_impl!(NonZeroU32: AsBytes);
3264    unsafe_impl!(NonZeroI32: AsBytes);
3265    unsafe_impl!(NonZeroU64: AsBytes);
3266    unsafe_impl!(NonZeroI64: AsBytes);
3267    unsafe_impl!(NonZeroU128: AsBytes);
3268    unsafe_impl!(NonZeroI128: AsBytes);
3269    unsafe_impl!(NonZeroUsize: AsBytes);
3270    unsafe_impl!(NonZeroIsize: AsBytes);
3271    /// SAFETY:
3272    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3273    ///   closure:
3274    ///   - Given `t: *mut NonZeroXxx` and `let r = *mut xxx`, `r` refers to an
3275    ///     object of the same size as that referred to by `t`. This is true
3276    ///     because `NonZeroXxx` and `xxx` have the same size. [1]
3277    ///   - Since the closure takes a `&xxx` argument, given a `Ptr<'a,
3278    ///     NonZeroXxx>` which satisfies the preconditions of
3279    ///     `TryFromBytes::<NonZeroXxx>::is_bit_valid`, it must be guaranteed
3280    ///     that the memory referenced by that `Ptr` always contains a valid
3281    ///     `xxx`. Since `NonZeroXxx`'s bytes are always initialized [1],
3282    ///     `is_bit_valid`'s precondition requires that the same is true of its
3283    ///     argument. Since `xxx`'s only bit validity invariant is that its
3284    ///     bytes must be initialized, this memory is guaranteed to contain a
3285    ///     valid `xxx`.
3286    ///   - The alignment of `NonZeroXxx` is equal to the alignment of `xxx`.
3287    ///     [1]
3288    ///   - The impl must only return `true` for its argument if the original
3289    ///     `Ptr<NonZeroXxx>` refers to a valid `NonZeroXxx`. The only `xxx`
3290    ///     which is not also a valid `NonZeroXxx` is 0. [1]
3291    ///
3292    /// [1] Per https://doc.rust-lang.org/core/num/struct.NonZeroU16.html:
3293    ///
3294    ///   `NonZeroU16` is guaranteed to have the same layout and bit validity as
3295    ///   `u16` with the exception that `0` is not a valid instance.
3296    unsafe_impl!(NonZeroU8: TryFromBytes; |n: &u8| *n != 0);
3297    unsafe_impl!(NonZeroI8: TryFromBytes; |n: &i8| *n != 0);
3298    unsafe_impl!(NonZeroU16: TryFromBytes; |n: &u16| *n != 0);
3299    unsafe_impl!(NonZeroI16: TryFromBytes; |n: &i16| *n != 0);
3300    unsafe_impl!(NonZeroU32: TryFromBytes; |n: &u32| *n != 0);
3301    unsafe_impl!(NonZeroI32: TryFromBytes; |n: &i32| *n != 0);
3302    unsafe_impl!(NonZeroU64: TryFromBytes; |n: &u64| *n != 0);
3303    unsafe_impl!(NonZeroI64: TryFromBytes; |n: &i64| *n != 0);
3304    unsafe_impl!(NonZeroU128: TryFromBytes; |n: &u128| *n != 0);
3305    unsafe_impl!(NonZeroI128: TryFromBytes; |n: &i128| *n != 0);
3306    unsafe_impl!(NonZeroUsize: TryFromBytes; |n: &usize| *n != 0);
3307    unsafe_impl!(NonZeroIsize: TryFromBytes; |n: &isize| *n != 0);
3308}
3309safety_comment! {
3310    /// SAFETY:
3311    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`,
3312    ///   `AsBytes`: The Rust compiler reuses `0` value to represent `None`, so
3313    ///   `size_of::<Option<NonZeroXxx>>() == size_of::<xxx>()`; see
3314    ///   `NonZeroXxx` documentation.
3315    /// - `Unaligned`: `NonZeroU8` and `NonZeroI8` document that
3316    ///   `Option<NonZeroU8>` and `Option<NonZeroI8>` both have size 1. [1] [2]
3317    ///   This is worded in a way that makes it unclear whether it's meant as a
3318    ///   guarantee, but given the purpose of those types, it's virtually
3319    ///   unthinkable that that would ever change. The only valid alignment for
3320    ///   a 1-byte type is 1.
3321    ///
3322    /// TODO(#429): Add quotes from documentation.
3323    ///
3324    /// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
3325    /// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
3326    ///
3327    /// TODO(https://github.com/rust-lang/rust/pull/104082): Cite documentation
3328    /// for layout guarantees.
3329    unsafe_impl!(Option<NonZeroU8>: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3330    unsafe_impl!(Option<NonZeroI8>: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3331    assert_unaligned!(Option<NonZeroU8>, Option<NonZeroI8>);
3332    unsafe_impl!(Option<NonZeroU16>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3333    unsafe_impl!(Option<NonZeroI16>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3334    unsafe_impl!(Option<NonZeroU32>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3335    unsafe_impl!(Option<NonZeroI32>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3336    unsafe_impl!(Option<NonZeroU64>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3337    unsafe_impl!(Option<NonZeroI64>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3338    unsafe_impl!(Option<NonZeroU128>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3339    unsafe_impl!(Option<NonZeroI128>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3340    unsafe_impl!(Option<NonZeroUsize>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3341    unsafe_impl!(Option<NonZeroIsize>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3342}
3343
3344safety_comment! {
3345    /// SAFETY:
3346    /// The following types can be transmuted from `[0u8; size_of::<T>()]`. [1]
3347    /// None of them contain `UnsafeCell`s, and so they all soundly implement
3348    /// `FromZeroes`.
3349    ///
3350    /// [1] Per
3351    /// https://doc.rust-lang.org/nightly/core/option/index.html#representation:
3352    ///
3353    ///   Rust guarantees to optimize the following types `T` such that
3354    ///   [`Option<T>`] has the same size and alignment as `T`. In some of these
3355    ///   cases, Rust further guarantees that `transmute::<_, Option<T>>([0u8;
3356    ///   size_of::<T>()])` is sound and produces `Option::<T>::None`. These
3357    ///   cases are identified by the second column:
3358    ///
3359    ///   | `T`                   | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
3360    ///   |-----------------------|-----------------------------------------------------------|
3361    ///   | [`Box<U>`]            | when `U: Sized`                                           |
3362    ///   | `&U`                  | when `U: Sized`                                           |
3363    ///   | `&mut U`              | when `U: Sized`                                           |
3364    ///   | [`ptr::NonNull<U>`]   | when `U: Sized`                                           |
3365    ///   | `fn`, `extern "C" fn` | always                                                    |
3366    ///
3367    /// TODO(#429), TODO(https://github.com/rust-lang/rust/pull/115333): Cite
3368    /// the Stable docs once they're available.
3369    #[cfg(feature = "alloc")]
3370    unsafe_impl!(
3371        #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3372        T => FromZeroes for Option<Box<T>>
3373    );
3374    unsafe_impl!(T => FromZeroes for Option<&'_ T>);
3375    unsafe_impl!(T => FromZeroes for Option<&'_ mut T>);
3376    unsafe_impl!(T => FromZeroes for Option<NonNull<T>>);
3377    unsafe_impl_for_power_set!(A, B, C, D, E, F, G, H, I, J, K, L -> M => FromZeroes for opt_fn!(...));
3378    unsafe_impl_for_power_set!(A, B, C, D, E, F, G, H, I, J, K, L -> M => FromZeroes for opt_extern_c_fn!(...));
3379}
3380
3381safety_comment! {
3382    /// SAFETY:
3383    /// Per reference [1]:
3384    /// "For all T, the following are guaranteed:
3385    /// size_of::<PhantomData<T>>() == 0
3386    /// align_of::<PhantomData<T>>() == 1".
3387    /// This gives:
3388    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: There
3389    ///   is only one possible sequence of 0 bytes, and `PhantomData` is
3390    ///   inhabited.
3391    /// - `AsBytes`: Since `PhantomData` has size 0, it contains no padding
3392    ///   bytes.
3393    /// - `Unaligned`: Per the preceding reference, `PhantomData` has alignment
3394    ///   1.
3395    ///
3396    /// [1] https://doc.rust-lang.org/std/marker/struct.PhantomData.html#layout-1
3397    unsafe_impl!(T: ?Sized => TryFromBytes for PhantomData<T>);
3398    unsafe_impl!(T: ?Sized => FromZeroes for PhantomData<T>);
3399    unsafe_impl!(T: ?Sized => FromBytes for PhantomData<T>);
3400    unsafe_impl!(T: ?Sized => AsBytes for PhantomData<T>);
3401    unsafe_impl!(T: ?Sized => Unaligned for PhantomData<T>);
3402    assert_unaligned!(PhantomData<()>, PhantomData<u8>, PhantomData<u64>);
3403}
3404safety_comment! {
3405    /// SAFETY:
3406    /// `Wrapping<T>` is guaranteed by its docs [1] to have the same layout and
3407    /// bit validity as `T`. Also, `Wrapping<T>` is `#[repr(transparent)]`, and
3408    /// has a single field, which is `pub`. Per the reference [2], this means
3409    /// that the `#[repr(transparent)]` attribute is "considered part of the
3410    /// public ABI".
3411    ///
3412    /// - `TryFromBytes`: The safety requirements for `unsafe_impl!` with an
3413    ///   `is_bit_valid` closure:
3414    ///   - Given `t: *mut Wrapping<T>` and `let r = *mut T`, `r` refers to an
3415    ///     object of the same size as that referred to by `t`. This is true
3416    ///     because `Wrapping<T>` and `T` have the same layout
3417    ///   - The alignment of `Wrapping<T>` is equal to the alignment of `T`.
3418    ///   - The impl must only return `true` for its argument if the original
3419    ///     `Ptr<Wrapping<T>>` refers to a valid `Wrapping<T>`. Since
3420    ///     `Wrapping<T>` has the same bit validity as `T`, and since our impl
3421    ///     just calls `T::is_bit_valid`, our impl returns `true` exactly when
3422    ///     its argument contains a valid `Wrapping<T>`.
3423    /// - `FromBytes`: Since `Wrapping<T>` has the same bit validity as `T`, if
3424    ///   `T: FromBytes`, then all initialized byte sequences are valid
3425    ///   instances of `Wrapping<T>`. Similarly, if `T: FromBytes`, then
3426    ///   `Wrapping<T>` doesn't contain any `UnsafeCell`s. Thus, `impl FromBytes
3427    ///   for Wrapping<T> where T: FromBytes` is a sound impl.
3428    /// - `AsBytes`: Since `Wrapping<T>` has the same bit validity as `T`, if
3429    ///   `T: AsBytes`, then all valid instances of `Wrapping<T>` have all of
3430    ///   their bytes initialized. Similarly, if `T: AsBytes`, then
3431    ///   `Wrapping<T>` doesn't contain any `UnsafeCell`s. Thus, `impl AsBytes
3432    ///   for Wrapping<T> where T: AsBytes` is a valid impl.
3433    /// - `Unaligned`: Since `Wrapping<T>` has the same layout as `T`,
3434    ///   `Wrapping<T>` has alignment 1 exactly when `T` does.
3435    ///
3436    /// [1] Per https://doc.rust-lang.org/core/num/struct.NonZeroU16.html:
3437    ///
3438    ///   `NonZeroU16` is guaranteed to have the same layout and bit validity as
3439    ///   `u16` with the exception that `0` is not a valid instance.
3440    ///
3441    /// TODO(#429): Add quotes from documentation.
3442    ///
3443    /// [1] TODO(https://doc.rust-lang.org/nightly/core/num/struct.Wrapping.html#layout-1):
3444    /// Reference this documentation once it's available on stable.
3445    ///
3446    /// [2] https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
3447    unsafe_impl!(T: TryFromBytes => TryFromBytes for Wrapping<T>; |candidate: Ptr<T>| {
3448        // SAFETY:
3449        // - Since `T` and `Wrapping<T>` have the same layout and bit validity
3450        //   and contain the same fields, `T` contains `UnsafeCell`s exactly
3451        //   where `Wrapping<T>` does. Thus, all memory and `UnsafeCell`
3452        //   preconditions of `T::is_bit_valid` hold exactly when the same
3453        //   preconditions for `Wrapping<T>::is_bit_valid` hold.
3454        // - By the same token, since `candidate` is guaranteed to have its
3455        //   bytes initialized where there are always initialized bytes in
3456        //   `Wrapping<T>`, the same is true for `T`.
3457        unsafe { T::is_bit_valid(candidate) }
3458    });
3459    unsafe_impl!(T: FromZeroes => FromZeroes for Wrapping<T>);
3460    unsafe_impl!(T: FromBytes => FromBytes for Wrapping<T>);
3461    unsafe_impl!(T: AsBytes => AsBytes for Wrapping<T>);
3462    unsafe_impl!(T: Unaligned => Unaligned for Wrapping<T>);
3463    assert_unaligned!(Wrapping<()>, Wrapping<u8>);
3464}
3465safety_comment! {
3466    // `MaybeUninit<T>` is `FromZeroes` and `FromBytes`, but never `AsBytes`
3467    // since it may contain uninitialized bytes.
3468    //
3469    /// SAFETY:
3470    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`:
3471    ///   `MaybeUninit<T>` has no restrictions on its contents. Unfortunately,
3472    ///   in addition to bit validity, `TryFromBytes`, `FromZeroes` and
3473    ///   `FromBytes` also require that implementers contain no `UnsafeCell`s.
3474    ///   Thus, we require `T: Trait` in order to ensure that `T` - and thus
3475    ///   `MaybeUninit<T>` - contains to `UnsafeCell`s. Thus, requiring that `T`
3476    ///   implement each of these traits is sufficient.
3477    /// - `Unaligned`: "MaybeUninit<T> is guaranteed to have the same size,
3478    ///    alignment, and ABI as T" [1]
3479    ///
3480    /// [1] https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#layout-1
3481    ///
3482    /// TODO(https://github.com/google/zerocopy/issues/251): If we split
3483    /// `FromBytes` and `RefFromBytes`, or if we introduce a separate
3484    /// `NoCell`/`Freeze` trait, we can relax the trait bounds for `FromZeroes`
3485    /// and `FromBytes`.
3486    unsafe_impl!(T: TryFromBytes => TryFromBytes for MaybeUninit<T>);
3487    unsafe_impl!(T: FromZeroes => FromZeroes for MaybeUninit<T>);
3488    unsafe_impl!(T: FromBytes => FromBytes for MaybeUninit<T>);
3489    unsafe_impl!(T: Unaligned => Unaligned for MaybeUninit<T>);
3490    assert_unaligned!(MaybeUninit<()>, MaybeUninit<u8>);
3491}
3492safety_comment! {
3493    /// SAFETY:
3494    /// `ManuallyDrop` has the same layout and bit validity as `T` [1], and
3495    /// accessing the inner value is safe (meaning that it's unsound to leave
3496    /// the inner value uninitialized while exposing the `ManuallyDrop` to safe
3497    /// code).
3498    /// - `FromZeroes`, `FromBytes`: Since it has the same layout as `T`, any
3499    ///   valid `T` is a valid `ManuallyDrop<T>`. If `T: FromZeroes`, a sequence
3500    ///   of zero bytes is a valid `T`, and thus a valid `ManuallyDrop<T>`. If
3501    ///   `T: FromBytes`, any sequence of bytes is a valid `T`, and thus a valid
3502    ///   `ManuallyDrop<T>`.
3503    /// - `AsBytes`: Since it has the same layout as `T`, and since it's unsound
3504    ///   to let safe code access a `ManuallyDrop` whose inner value is
3505    ///   uninitialized, safe code can only ever access a `ManuallyDrop` whose
3506    ///   contents are a valid `T`. Since `T: AsBytes`, this means that safe
3507    ///   code can only ever access a `ManuallyDrop` with all initialized bytes.
3508    /// - `Unaligned`: `ManuallyDrop` has the same layout (and thus alignment)
3509    ///   as `T`, and `T: Unaligned` guarantees that that alignment is 1.
3510    ///
3511    ///   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
3512    ///   validity as `T`
3513    ///
3514    /// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
3515    ///
3516    /// TODO(#429):
3517    /// - Add quotes from docs.
3518    /// - Once [1] (added in
3519    /// https://github.com/rust-lang/rust/pull/115522) is available on stable,
3520    /// quote the stable docs instead of the nightly docs.
3521    unsafe_impl!(T: ?Sized + FromZeroes => FromZeroes for ManuallyDrop<T>);
3522    unsafe_impl!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>);
3523    unsafe_impl!(T: ?Sized + AsBytes => AsBytes for ManuallyDrop<T>);
3524    unsafe_impl!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>);
3525    assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
3526}
3527safety_comment! {
3528    /// SAFETY:
3529    /// Per the reference [1]:
3530    ///
3531    ///   An array of `[T; N]` has a size of `size_of::<T>() * N` and the same
3532    ///   alignment of `T`. Arrays are laid out so that the zero-based `nth`
3533    ///   element of the array is offset from the start of the array by `n *
3534    ///   size_of::<T>()` bytes.
3535    ///
3536    ///   ...
3537    ///
3538    ///   Slices have the same layout as the section of the array they slice.
3539    ///
3540    /// In other words, the layout of a `[T]` or `[T; N]` is a sequence of `T`s
3541    /// laid out back-to-back with no bytes in between. Therefore, `[T]` or `[T;
3542    /// N]` are `TryFromBytes`, `FromZeroes`, `FromBytes`, and `AsBytes` if `T`
3543    /// is (respectively). Furthermore, since an array/slice has "the same
3544    /// alignment of `T`", `[T]` and `[T; N]` are `Unaligned` if `T` is.
3545    ///
3546    /// Note that we don't `assert_unaligned!` for slice types because
3547    /// `assert_unaligned!` uses `align_of`, which only works for `Sized` types.
3548    ///
3549    /// [1] https://doc.rust-lang.org/reference/type-layout.html#array-layout
3550    unsafe_impl!(const N: usize, T: FromZeroes => FromZeroes for [T; N]);
3551    unsafe_impl!(const N: usize, T: FromBytes => FromBytes for [T; N]);
3552    unsafe_impl!(const N: usize, T: AsBytes => AsBytes for [T; N]);
3553    unsafe_impl!(const N: usize, T: Unaligned => Unaligned for [T; N]);
3554    assert_unaligned!([(); 0], [(); 1], [u8; 0], [u8; 1]);
3555    unsafe_impl!(T: TryFromBytes => TryFromBytes for [T]; |c: Ptr<[T]>| {
3556        // SAFETY: Assuming the preconditions of `is_bit_valid` are satisfied,
3557        // so too will the postcondition: that, if `is_bit_valid(candidate)`
3558        // returns true, `*candidate` contains a valid `Self`. Per the reference
3559        // [1]:
3560        //
3561        //   An array of `[T; N]` has a size of `size_of::<T>() * N` and the
3562        //   same alignment of `T`. Arrays are laid out so that the zero-based
3563        //   `nth` element of the array is offset from the start of the array by
3564        //   `n * size_of::<T>()` bytes.
3565        //
3566        //   ...
3567        //
3568        //   Slices have the same layout as the section of the array they slice.
3569        //
3570        // In other words, the layout of a `[T] is a sequence of `T`s laid out
3571        // back-to-back with no bytes in between. If all elements in `candidate`
3572        // are `is_bit_valid`, so too is `candidate`.
3573        //
3574        // Note that any of the below calls may panic, but it would still be
3575        // sound even if it did. `is_bit_valid` does not promise that it will
3576        // not panic (in fact, it explicitly warns that it's a possibility), and
3577        // we have not violated any safety invariants that we must fix before
3578        // returning.
3579        c.iter().all(|elem|
3580            // SAFETY: We uphold the safety contract of `is_bit_valid(elem)`, by
3581            // precondition on the surrounding call to `is_bit_valid`. The
3582            // memory referenced by `elem` is contained entirely within `c`, and
3583            // satisfies the preconditions satisfied by `c`. By axiom, we assume
3584            // that `Iterator:all` does not invalidate these preconditions
3585            // (e.g., by writing to `elem`.) Since `elem` is derived from `c`,
3586            // it is only possible for uninitialized bytes to occur in `elem` at
3587            // the same bytes they occur within `c`.
3588            unsafe { <T as TryFromBytes>::is_bit_valid(elem) }
3589        )
3590    });
3591    unsafe_impl!(T: FromZeroes => FromZeroes for [T]);
3592    unsafe_impl!(T: FromBytes => FromBytes for [T]);
3593    unsafe_impl!(T: AsBytes => AsBytes for [T]);
3594    unsafe_impl!(T: Unaligned => Unaligned for [T]);
3595}
3596safety_comment! {
3597    /// SAFETY:
3598    /// - `FromZeroes`: For thin pointers (note that `T: Sized`), the zero
3599    ///   pointer is considered "null". [1] No operations which require
3600    ///   provenance are legal on null pointers, so this is not a footgun.
3601    ///
3602    /// NOTE(#170): Implementing `FromBytes` and `AsBytes` for raw pointers
3603    /// would be sound, but carries provenance footguns. We want to support
3604    /// `FromBytes` and `AsBytes` for raw pointers eventually, but we are
3605    /// holding off until we can figure out how to address those footguns.
3606    ///
3607    /// [1] TODO(https://github.com/rust-lang/rust/pull/116988): Cite the
3608    /// documentation once this PR lands.
3609    unsafe_impl!(T => FromZeroes for *const T);
3610    unsafe_impl!(T => FromZeroes for *mut T);
3611}
3612
3613// SIMD support
3614//
3615// Per the Unsafe Code Guidelines Reference [1]:
3616//
3617//   Packed SIMD vector types are `repr(simd)` homogeneous tuple-structs
3618//   containing `N` elements of type `T` where `N` is a power-of-two and the
3619//   size and alignment requirements of `T` are equal:
3620//
3621//   ```rust
3622//   #[repr(simd)]
3623//   struct Vector<T, N>(T_0, ..., T_(N - 1));
3624//   ```
3625//
3626//   ...
3627//
3628//   The size of `Vector` is `N * size_of::<T>()` and its alignment is an
3629//   implementation-defined function of `T` and `N` greater than or equal to
3630//   `align_of::<T>()`.
3631//
3632//   ...
3633//
3634//   Vector elements are laid out in source field order, enabling random access
3635//   to vector elements by reinterpreting the vector as an array:
3636//
3637//   ```rust
3638//   union U {
3639//      vec: Vector<T, N>,
3640//      arr: [T; N]
3641//   }
3642//
3643//   assert_eq!(size_of::<Vector<T, N>>(), size_of::<[T; N]>());
3644//   assert!(align_of::<Vector<T, N>>() >= align_of::<[T; N]>());
3645//
3646//   unsafe {
3647//     let u = U { vec: Vector<T, N>(t_0, ..., t_(N - 1)) };
3648//
3649//     assert_eq!(u.vec.0, u.arr[0]);
3650//     // ...
3651//     assert_eq!(u.vec.(N - 1), u.arr[N - 1]);
3652//   }
3653//   ```
3654//
3655// Given this background, we can observe that:
3656// - The size and bit pattern requirements of a SIMD type are equivalent to the
3657//   equivalent array type. Thus, for any SIMD type whose primitive `T` is
3658//   `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes`, that SIMD type is
3659//   also `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes` respectively.
3660// - Since no upper bound is placed on the alignment, no SIMD type can be
3661//   guaranteed to be `Unaligned`.
3662//
3663// Also per [1]:
3664//
3665//   This chapter represents the consensus from issue #38. The statements in
3666//   here are not (yet) "guaranteed" not to change until an RFC ratifies them.
3667//
3668// See issue #38 [2]. While this behavior is not technically guaranteed, the
3669// likelihood that the behavior will change such that SIMD types are no longer
3670// `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes` is next to zero, as
3671// that would defeat the entire purpose of SIMD types. Nonetheless, we put this
3672// behavior behind the `simd` Cargo feature, which requires consumers to opt
3673// into this stability hazard.
3674//
3675// [1] https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
3676// [2] https://github.com/rust-lang/unsafe-code-guidelines/issues/38
3677#[cfg(feature = "simd")]
3678#[cfg_attr(doc_cfg, doc(cfg(feature = "simd")))]
3679mod simd {
3680    /// Defines a module which implements `TryFromBytes`, `FromZeroes`,
3681    /// `FromBytes`, and `AsBytes` for a set of types from a module in
3682    /// `core::arch`.
3683    ///
3684    /// `$arch` is both the name of the defined module and the name of the
3685    /// module in `core::arch`, and `$typ` is the list of items from that module
3686    /// to implement `FromZeroes`, `FromBytes`, and `AsBytes` for.
3687    #[allow(unused_macros)] // `allow(unused_macros)` is needed because some
3688                            // target/feature combinations don't emit any impls
3689                            // and thus don't use this macro.
3690    macro_rules! simd_arch_mod {
3691        (#[cfg $cfg:tt] $arch:ident, $mod:ident, $($typ:ident),*) => {
3692            #[cfg $cfg]
3693            #[cfg_attr(doc_cfg, doc(cfg $cfg))]
3694            mod $mod {
3695                use core::arch::$arch::{$($typ),*};
3696
3697                use crate::*;
3698                impl_known_layout!($($typ),*);
3699                safety_comment! {
3700                    /// SAFETY:
3701                    /// See comment on module definition for justification.
3702                    $( unsafe_impl!($typ: TryFromBytes, FromZeroes, FromBytes, AsBytes); )*
3703                }
3704            }
3705        };
3706    }
3707
3708    #[rustfmt::skip]
3709    const _: () = {
3710        simd_arch_mod!(
3711            #[cfg(target_arch = "x86")]
3712            x86, x86, __m128, __m128d, __m128i, __m256, __m256d, __m256i
3713        );
3714        simd_arch_mod!(
3715            #[cfg(all(feature = "simd-nightly", target_arch = "x86"))]
3716            x86, x86_nightly, __m512bh, __m512, __m512d, __m512i
3717        );
3718        simd_arch_mod!(
3719            #[cfg(target_arch = "x86_64")]
3720            x86_64, x86_64, __m128, __m128d, __m128i, __m256, __m256d, __m256i
3721        );
3722        simd_arch_mod!(
3723            #[cfg(all(feature = "simd-nightly", target_arch = "x86_64"))]
3724            x86_64, x86_64_nightly, __m512bh, __m512, __m512d, __m512i
3725        );
3726        simd_arch_mod!(
3727            #[cfg(target_arch = "wasm32")]
3728            wasm32, wasm32, v128
3729        );
3730        simd_arch_mod!(
3731            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc"))]
3732            powerpc, powerpc, vector_bool_long, vector_double, vector_signed_long, vector_unsigned_long
3733        );
3734        simd_arch_mod!(
3735            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc64"))]
3736            powerpc64, powerpc64, vector_bool_long, vector_double, vector_signed_long, vector_unsigned_long
3737        );
3738        simd_arch_mod!(
3739            #[cfg(target_arch = "aarch64")]
3740            aarch64, aarch64, float32x2_t, float32x4_t, float64x1_t, float64x2_t, int8x8_t, int8x8x2_t,
3741            int8x8x3_t, int8x8x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int16x4_t,
3742            int16x8_t, int32x2_t, int32x4_t, int64x1_t, int64x2_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t,
3743            poly8x8x4_t, poly8x16_t, poly8x16x2_t, poly8x16x3_t, poly8x16x4_t, poly16x4_t, poly16x8_t,
3744            poly64x1_t, poly64x2_t, uint8x8_t, uint8x8x2_t, uint8x8x3_t, uint8x8x4_t, uint8x16_t,
3745            uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint16x4_t, uint16x8_t, uint32x2_t, uint32x4_t,
3746            uint64x1_t, uint64x2_t
3747        );
3748        simd_arch_mod!(
3749            #[cfg(all(feature = "simd-nightly", target_arch = "arm"))]
3750            arm, arm, int8x4_t, uint8x4_t
3751        );
3752    };
3753}
3754
3755/// Safely transmutes a value of one type to a value of another type of the same
3756/// size.
3757///
3758/// The expression `$e` must have a concrete type, `T`, which implements
3759/// `AsBytes`. The `transmute!` expression must also have a concrete type, `U`
3760/// (`U` is inferred from the calling context), and `U` must implement
3761/// `FromBytes`.
3762///
3763/// Note that the `T` produced by the expression `$e` will *not* be dropped.
3764/// Semantically, its bits will be copied into a new value of type `U`, the
3765/// original `T` will be forgotten, and the value of type `U` will be returned.
3766///
3767/// # Examples
3768///
3769/// ```
3770/// # use zerocopy::transmute;
3771/// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3772///
3773/// let two_dimensional: [[u8; 4]; 2] = transmute!(one_dimensional);
3774///
3775/// assert_eq!(two_dimensional, [[0, 1, 2, 3], [4, 5, 6, 7]]);
3776/// ```
3777#[macro_export]
3778macro_rules! transmute {
3779    ($e:expr) => {{
3780        // NOTE: This must be a macro (rather than a function with trait bounds)
3781        // because there's no way, in a generic context, to enforce that two
3782        // types have the same size. `core::mem::transmute` uses compiler magic
3783        // to enforce this so long as the types are concrete.
3784
3785        let e = $e;
3786        if false {
3787            // This branch, though never taken, ensures that the type of `e` is
3788            // `AsBytes` and that the type of this macro invocation expression
3789            // is `FromBytes`.
3790
3791            struct AssertIsAsBytes<T: $crate::AsBytes>(T);
3792            let _ = AssertIsAsBytes(e);
3793
3794            struct AssertIsFromBytes<U: $crate::FromBytes>(U);
3795            #[allow(unused, unreachable_code)]
3796            let u = AssertIsFromBytes(loop {});
3797            u.0
3798        } else {
3799            // SAFETY: `core::mem::transmute` ensures that the type of `e` and
3800            // the type of this macro invocation expression have the same size.
3801            // We know this transmute is safe thanks to the `AsBytes` and
3802            // `FromBytes` bounds enforced by the `false` branch.
3803            //
3804            // We use this reexport of `core::mem::transmute` because we know it
3805            // will always be available for crates which are using the 2015
3806            // edition of Rust. By contrast, if we were to use
3807            // `std::mem::transmute`, this macro would not work for such crates
3808            // in `no_std` contexts, and if we were to use
3809            // `core::mem::transmute`, this macro would not work in `std`
3810            // contexts in which `core` was not manually imported. This is not a
3811            // problem for 2018 edition crates.
3812            unsafe {
3813                // Clippy: It's okay to transmute a type to itself.
3814                #[allow(clippy::useless_transmute, clippy::missing_transmute_annotations)]
3815                $crate::macro_util::core_reexport::mem::transmute(e)
3816            }
3817        }
3818    }}
3819}
3820
3821/// Safely transmutes a mutable or immutable reference of one type to an
3822/// immutable reference of another type of the same size.
3823///
3824/// The expression `$e` must have a concrete type, `&T` or `&mut T`, where `T:
3825/// Sized + AsBytes`. The `transmute_ref!` expression must also have a concrete
3826/// type, `&U` (`U` is inferred from the calling context), where `U: Sized +
3827/// FromBytes`. It must be the case that `align_of::<T>() >= align_of::<U>()`.
3828///
3829/// The lifetime of the input type, `&T` or `&mut T`, must be the same as or
3830/// outlive the lifetime of the output type, `&U`.
3831///
3832/// # Examples
3833///
3834/// ```
3835/// # use zerocopy::transmute_ref;
3836/// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3837///
3838/// let two_dimensional: &[[u8; 4]; 2] = transmute_ref!(&one_dimensional);
3839///
3840/// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);
3841/// ```
3842///
3843/// # Alignment increase error message
3844///
3845/// Because of limitations on macros, the error message generated when
3846/// `transmute_ref!` is used to transmute from a type of lower alignment to a
3847/// type of higher alignment is somewhat confusing. For example, the following
3848/// code:
3849///
3850/// ```compile_fail
3851/// const INCREASE_ALIGNMENT: &u16 = zerocopy::transmute_ref!(&[0u8; 2]);
3852/// ```
3853///
3854/// ...generates the following error:
3855///
3856/// ```text
3857/// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
3858///  --> src/lib.rs:1524:34
3859///   |
3860/// 5 | const INCREASE_ALIGNMENT: &u16 = zerocopy::transmute_ref!(&[0u8; 2]);
3861///   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3862///   |
3863///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)
3864///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
3865///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `transmute_ref` (in Nightly builds, run with -Z macro-backtrace for more info)
3866/// ```
3867///
3868/// This is saying that `max(align_of::<T>(), align_of::<U>()) !=
3869/// align_of::<T>()`, which is equivalent to `align_of::<T>() <
3870/// align_of::<U>()`.
3871#[macro_export]
3872macro_rules! transmute_ref {
3873    ($e:expr) => {{
3874        // NOTE: This must be a macro (rather than a function with trait bounds)
3875        // because there's no way, in a generic context, to enforce that two
3876        // types have the same size or alignment.
3877
3878        // Ensure that the source type is a reference or a mutable reference
3879        // (note that mutable references are implicitly reborrowed here).
3880        let e: &_ = $e;
3881
3882        #[allow(unused, clippy::diverging_sub_expression)]
3883        if false {
3884            // This branch, though never taken, ensures that the type of `e` is
3885            // `&T` where `T: 't + Sized + AsBytes`, that the type of this macro
3886            // expression is `&U` where `U: 'u + Sized + FromBytes`, and that
3887            // `'t` outlives `'u`.
3888
3889            struct AssertIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
3890            let _ = AssertIsAsBytes(e);
3891
3892            struct AssertIsFromBytes<'a, U: ::core::marker::Sized + $crate::FromBytes>(&'a U);
3893            #[allow(unused, unreachable_code)]
3894            let u = AssertIsFromBytes(loop {});
3895            u.0
3896        } else if false {
3897            // This branch, though never taken, ensures that `size_of::<T>() ==
3898            // size_of::<U>()` and that that `align_of::<T>() >=
3899            // align_of::<U>()`.
3900
3901            // `t` is inferred to have type `T` because it's assigned to `e` (of
3902            // type `&T`) as `&t`.
3903            let mut t = unreachable!();
3904            e = &t;
3905
3906            // `u` is inferred to have type `U` because it's used as `&u` as the
3907            // value returned from this branch.
3908            let u;
3909
3910            $crate::assert_size_eq!(t, u);
3911            $crate::assert_align_gt_eq!(t, u);
3912
3913            &u
3914        } else {
3915            // SAFETY: For source type `Src` and destination type `Dst`:
3916            // - We know that `Src: AsBytes` and `Dst: FromBytes` thanks to the
3917            //   uses of `AssertIsAsBytes` and `AssertIsFromBytes` above.
3918            // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
3919            //   the use of `assert_size_eq!` above.
3920            // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
3921            //   the use of `assert_align_gt_eq!` above.
3922            unsafe { $crate::macro_util::transmute_ref(e) }
3923        }
3924    }}
3925}
3926
3927/// Safely transmutes a mutable reference of one type to an mutable reference of
3928/// another type of the same size.
3929///
3930/// The expression `$e` must have a concrete type, `&mut T`, where `T: Sized +
3931/// AsBytes`. The `transmute_mut!` expression must also have a concrete type,
3932/// `&mut U` (`U` is inferred from the calling context), where `U: Sized +
3933/// FromBytes`. It must be the case that `align_of::<T>() >= align_of::<U>()`.
3934///
3935/// The lifetime of the input type, `&mut T`, must be the same as or outlive the
3936/// lifetime of the output type, `&mut U`.
3937///
3938/// # Examples
3939///
3940/// ```
3941/// # use zerocopy::transmute_mut;
3942/// let mut one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3943///
3944/// let two_dimensional: &mut [[u8; 4]; 2] = transmute_mut!(&mut one_dimensional);
3945///
3946/// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);
3947///
3948/// two_dimensional.reverse();
3949///
3950/// assert_eq!(one_dimensional, [4, 5, 6, 7, 0, 1, 2, 3]);
3951/// ```
3952///
3953/// # Alignment increase error message
3954///
3955/// Because of limitations on macros, the error message generated when
3956/// `transmute_mut!` is used to transmute from a type of lower alignment to a
3957/// type of higher alignment is somewhat confusing. For example, the following
3958/// code:
3959///
3960/// ```compile_fail
3961/// const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
3962/// ```
3963///
3964/// ...generates the following error:
3965///
3966/// ```text
3967/// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
3968///  --> src/lib.rs:1524:34
3969///   |
3970/// 5 | const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
3971///   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3972///   |
3973///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)
3974///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
3975///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
3976/// ```
3977///
3978/// This is saying that `max(align_of::<T>(), align_of::<U>()) !=
3979/// align_of::<T>()`, which is equivalent to `align_of::<T>() <
3980/// align_of::<U>()`.
3981#[macro_export]
3982macro_rules! transmute_mut {
3983    ($e:expr) => {{
3984        // NOTE: This must be a macro (rather than a function with trait bounds)
3985        // because there's no way, in a generic context, to enforce that two
3986        // types have the same size or alignment.
3987
3988        // Ensure that the source type is a mutable reference.
3989        let e: &mut _ = $e;
3990
3991        #[allow(unused, clippy::diverging_sub_expression)]
3992        if false {
3993            // This branch, though never taken, ensures that the type of `e` is
3994            // `&mut T` where `T: 't + Sized + FromBytes + AsBytes`, that the
3995            // type of this macro expression is `&mut U` where `U: 'u + Sized +
3996            // FromBytes + AsBytes`.
3997
3998            // We use immutable references here rather than mutable so that, if
3999            // this macro is used in a const context (in which, as of this
4000            // writing, mutable references are banned), the error message
4001            // appears to originate in the user's code rather than in the
4002            // internals of this macro.
4003            struct AssertSrcIsFromBytes<'a, T: ::core::marker::Sized + $crate::FromBytes>(&'a T);
4004            struct AssertSrcIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
4005            struct AssertDstIsFromBytes<'a, T: ::core::marker::Sized + $crate::FromBytes>(&'a T);
4006            struct AssertDstIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
4007
4008            if true {
4009                let _ = AssertSrcIsFromBytes(&*e);
4010            } else {
4011                let _ = AssertSrcIsAsBytes(&*e);
4012            }
4013
4014            if true {
4015                #[allow(unused, unreachable_code)]
4016                let u = AssertDstIsFromBytes(loop {});
4017                &mut *u.0
4018            } else {
4019                #[allow(unused, unreachable_code)]
4020                let u = AssertDstIsAsBytes(loop {});
4021                &mut *u.0
4022            }
4023        } else if false {
4024            // This branch, though never taken, ensures that `size_of::<T>() ==
4025            // size_of::<U>()` and that that `align_of::<T>() >=
4026            // align_of::<U>()`.
4027
4028            // `t` is inferred to have type `T` because it's assigned to `e` (of
4029            // type `&mut T`) as `&mut t`.
4030            let mut t = unreachable!();
4031            e = &mut t;
4032
4033            // `u` is inferred to have type `U` because it's used as `&mut u` as
4034            // the value returned from this branch.
4035            let u;
4036
4037            $crate::assert_size_eq!(t, u);
4038            $crate::assert_align_gt_eq!(t, u);
4039
4040            &mut u
4041        } else {
4042            // SAFETY: For source type `Src` and destination type `Dst`:
4043            // - We know that `Src: FromBytes + AsBytes` and `Dst: FromBytes +
4044            //   AsBytes` thanks to the uses of `AssertSrcIsFromBytes`,
4045            //   `AssertSrcIsAsBytes`, `AssertDstIsFromBytes`, and
4046            //   `AssertDstIsAsBytes` above.
4047            // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
4048            //   the use of `assert_size_eq!` above.
4049            // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
4050            //   the use of `assert_align_gt_eq!` above.
4051            unsafe { $crate::macro_util::transmute_mut(e) }
4052        }
4053    }}
4054}
4055
4056/// Includes a file and safely transmutes it to a value of an arbitrary type.
4057///
4058/// The file will be included as a byte array, `[u8; N]`, which will be
4059/// transmuted to another type, `T`. `T` is inferred from the calling context,
4060/// and must implement [`FromBytes`].
4061///
4062/// The file is located relative to the current file (similarly to how modules
4063/// are found). The provided path is interpreted in a platform-specific way at
4064/// compile time. So, for instance, an invocation with a Windows path containing
4065/// backslashes `\` would not compile correctly on Unix.
4066///
4067/// `include_value!` is ignorant of byte order. For byte order-aware types, see
4068/// the [`byteorder`] module.
4069///
4070/// # Examples
4071///
4072/// Assume there are two files in the same directory with the following
4073/// contents:
4074///
4075/// File `data` (no trailing newline):
4076///
4077/// ```text
4078/// abcd
4079/// ```
4080///
4081/// File `main.rs`:
4082///
4083/// ```rust
4084/// use zerocopy::include_value;
4085/// # macro_rules! include_value {
4086/// # ($file:expr) => { zerocopy::include_value!(concat!("../testdata/include_value/", $file)) };
4087/// # }
4088///
4089/// fn main() {
4090///     let as_u32: u32 = include_value!("data");
4091///     assert_eq!(as_u32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));
4092///     let as_i32: i32 = include_value!("data");
4093///     assert_eq!(as_i32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));
4094/// }
4095/// ```
4096#[doc(alias("include_bytes", "include_data", "include_type"))]
4097#[macro_export]
4098macro_rules! include_value {
4099    ($file:expr $(,)?) => {
4100        $crate::transmute!(*::core::include_bytes!($file))
4101    };
4102}
4103
4104/// A typed reference derived from a byte slice.
4105///
4106/// A `Ref<B, T>` is a reference to a `T` which is stored in a byte slice, `B`.
4107/// Unlike a native reference (`&T` or `&mut T`), `Ref<B, T>` has the same
4108/// mutability as the byte slice it was constructed from (`B`).
4109///
4110/// # Examples
4111///
4112/// `Ref` can be used to treat a sequence of bytes as a structured type, and to
4113/// read and write the fields of that type as if the byte slice reference were
4114/// simply a reference to that type.
4115///
4116/// ```rust
4117/// # #[cfg(feature = "derive")] { // This example uses derives, and won't compile without them
4118/// use zerocopy::{AsBytes, ByteSlice, ByteSliceMut, FromBytes, FromZeroes, Ref, Unaligned};
4119///
4120/// #[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
4121/// #[repr(C)]
4122/// struct UdpHeader {
4123///     src_port: [u8; 2],
4124///     dst_port: [u8; 2],
4125///     length: [u8; 2],
4126///     checksum: [u8; 2],
4127/// }
4128///
4129/// struct UdpPacket<B> {
4130///     header: Ref<B, UdpHeader>,
4131///     body: B,
4132/// }
4133///
4134/// impl<B: ByteSlice> UdpPacket<B> {
4135///     pub fn parse(bytes: B) -> Option<UdpPacket<B>> {
4136///         let (header, body) = Ref::new_unaligned_from_prefix(bytes)?;
4137///         Some(UdpPacket { header, body })
4138///     }
4139///
4140///     pub fn get_src_port(&self) -> [u8; 2] {
4141///         self.header.src_port
4142///     }
4143/// }
4144///
4145/// impl<B: ByteSliceMut> UdpPacket<B> {
4146///     pub fn set_src_port(&mut self, src_port: [u8; 2]) {
4147///         self.header.src_port = src_port;
4148///     }
4149/// }
4150/// # }
4151/// ```
4152pub struct Ref<B, T: ?Sized>(B, PhantomData<T>);
4153
4154/// Deprecated: prefer [`Ref`] instead.
4155#[deprecated(since = "0.7.0", note = "LayoutVerified has been renamed to Ref")]
4156#[doc(hidden)]
4157pub type LayoutVerified<B, T> = Ref<B, T>;
4158
4159impl<B, T> Ref<B, T>
4160where
4161    B: ByteSlice,
4162{
4163    /// Constructs a new `Ref`.
4164    ///
4165    /// `new` verifies that `bytes.len() == size_of::<T>()` and that `bytes` is
4166    /// aligned to `align_of::<T>()`, and constructs a new `Ref`. If either of
4167    /// these checks fail, it returns `None`.
4168    #[inline]
4169    pub fn new(bytes: B) -> Option<Ref<B, T>> {
4170        if bytes.len() != mem::size_of::<T>() || !util::aligned_to::<_, T>(bytes.deref()) {
4171            return None;
4172        }
4173        Some(Ref(bytes, PhantomData))
4174    }
4175
4176    /// Constructs a new `Ref` from the prefix of a byte slice.
4177    ///
4178    /// `new_from_prefix` verifies that `bytes.len() >= size_of::<T>()` and that
4179    /// `bytes` is aligned to `align_of::<T>()`. It consumes the first
4180    /// `size_of::<T>()` bytes from `bytes` to construct a `Ref`, and returns
4181    /// the remaining bytes to the caller. If either the length or alignment
4182    /// checks fail, it returns `None`.
4183    #[inline]
4184    pub fn new_from_prefix(bytes: B) -> Option<(Ref<B, T>, B)> {
4185        if bytes.len() < mem::size_of::<T>() || !util::aligned_to::<_, T>(bytes.deref()) {
4186            return None;
4187        }
4188        let (bytes, suffix) = bytes.split_at(mem::size_of::<T>());
4189        Some((Ref(bytes, PhantomData), suffix))
4190    }
4191
4192    /// Constructs a new `Ref` from the suffix of a byte slice.
4193    ///
4194    /// `new_from_suffix` verifies that `bytes.len() >= size_of::<T>()` and that
4195    /// the last `size_of::<T>()` bytes of `bytes` are aligned to
4196    /// `align_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4197    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4198    /// caller. If either the length or alignment checks fail, it returns
4199    /// `None`.
4200    #[inline]
4201    pub fn new_from_suffix(bytes: B) -> Option<(B, Ref<B, T>)> {
4202        let bytes_len = bytes.len();
4203        let split_at = bytes_len.checked_sub(mem::size_of::<T>())?;
4204        let (prefix, bytes) = bytes.split_at(split_at);
4205        if !util::aligned_to::<_, T>(bytes.deref()) {
4206            return None;
4207        }
4208        Some((prefix, Ref(bytes, PhantomData)))
4209    }
4210}
4211
4212impl<B, T> Ref<B, [T]>
4213where
4214    B: ByteSlice,
4215{
4216    /// Constructs a new `Ref` of a slice type.
4217    ///
4218    /// `new_slice` verifies that `bytes.len()` is a multiple of
4219    /// `size_of::<T>()` and that `bytes` is aligned to `align_of::<T>()`, and
4220    /// constructs a new `Ref`. If either of these checks fail, it returns
4221    /// `None`.
4222    ///
4223    /// # Panics
4224    ///
4225    /// `new_slice` panics if `T` is a zero-sized type.
4226    #[inline]
4227    pub fn new_slice(bytes: B) -> Option<Ref<B, [T]>> {
4228        let remainder = bytes
4229            .len()
4230            .checked_rem(mem::size_of::<T>())
4231            .expect("Ref::new_slice called on a zero-sized type");
4232        if remainder != 0 || !util::aligned_to::<_, T>(bytes.deref()) {
4233            return None;
4234        }
4235        Some(Ref(bytes, PhantomData))
4236    }
4237
4238    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice.
4239    ///
4240    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4241    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4242    /// first `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4243    /// and returns the remaining bytes to the caller. It also ensures that
4244    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4245    /// length, alignment, or overflow checks fail, it returns `None`.
4246    ///
4247    /// # Panics
4248    ///
4249    /// `new_slice_from_prefix` panics if `T` is a zero-sized type.
4250    #[inline]
4251    pub fn new_slice_from_prefix(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4252        let expected_len = match mem::size_of::<T>().checked_mul(count) {
4253            Some(len) => len,
4254            None => return None,
4255        };
4256        if bytes.len() < expected_len {
4257            return None;
4258        }
4259        let (prefix, bytes) = bytes.split_at(expected_len);
4260        Self::new_slice(prefix).map(move |l| (l, bytes))
4261    }
4262
4263    /// Constructs a new `Ref` of a slice type from the suffix of a byte slice.
4264    ///
4265    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4266    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4267    /// last `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4268    /// and returns the preceding bytes to the caller. It also ensures that
4269    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4270    /// length, alignment, or overflow checks fail, it returns `None`.
4271    ///
4272    /// # Panics
4273    ///
4274    /// `new_slice_from_suffix` panics if `T` is a zero-sized type.
4275    #[inline]
4276    pub fn new_slice_from_suffix(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4277        let expected_len = match mem::size_of::<T>().checked_mul(count) {
4278            Some(len) => len,
4279            None => return None,
4280        };
4281        let split_at = bytes.len().checked_sub(expected_len)?;
4282        let (bytes, suffix) = bytes.split_at(split_at);
4283        Self::new_slice(suffix).map(move |l| (bytes, l))
4284    }
4285}
4286
4287fn map_zeroed<B: ByteSliceMut, T: ?Sized>(opt: Option<Ref<B, T>>) -> Option<Ref<B, T>> {
4288    match opt {
4289        Some(mut r) => {
4290            r.0.fill(0);
4291            Some(r)
4292        }
4293        None => None,
4294    }
4295}
4296
4297fn map_prefix_tuple_zeroed<B: ByteSliceMut, T: ?Sized>(
4298    opt: Option<(Ref<B, T>, B)>,
4299) -> Option<(Ref<B, T>, B)> {
4300    match opt {
4301        Some((mut r, rest)) => {
4302            r.0.fill(0);
4303            Some((r, rest))
4304        }
4305        None => None,
4306    }
4307}
4308
4309fn map_suffix_tuple_zeroed<B: ByteSliceMut, T: ?Sized>(
4310    opt: Option<(B, Ref<B, T>)>,
4311) -> Option<(B, Ref<B, T>)> {
4312    map_prefix_tuple_zeroed(opt.map(|(a, b)| (b, a))).map(|(a, b)| (b, a))
4313}
4314
4315impl<B, T> Ref<B, T>
4316where
4317    B: ByteSliceMut,
4318{
4319    /// Constructs a new `Ref` after zeroing the bytes.
4320    ///
4321    /// `new_zeroed` verifies that `bytes.len() == size_of::<T>()` and that
4322    /// `bytes` is aligned to `align_of::<T>()`, and constructs a new `Ref`. If
4323    /// either of these checks fail, it returns `None`.
4324    ///
4325    /// If the checks succeed, then `bytes` will be initialized to zero. This
4326    /// can be useful when re-using buffers to ensure that sensitive data
4327    /// previously stored in the buffer is not leaked.
4328    #[inline(always)]
4329    pub fn new_zeroed(bytes: B) -> Option<Ref<B, T>> {
4330        map_zeroed(Self::new(bytes))
4331    }
4332
4333    /// Constructs a new `Ref` from the prefix of a byte slice, zeroing the
4334    /// prefix.
4335    ///
4336    /// `new_from_prefix_zeroed` verifies that `bytes.len() >= size_of::<T>()`
4337    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the first
4338    /// `size_of::<T>()` bytes from `bytes` to construct a `Ref`, and returns
4339    /// the remaining bytes to the caller. If either the length or alignment
4340    /// checks fail, it returns `None`.
4341    ///
4342    /// If the checks succeed, then the prefix which is consumed will be
4343    /// initialized to zero. This can be useful when re-using buffers to ensure
4344    /// that sensitive data previously stored in the buffer is not leaked.
4345    #[inline(always)]
4346    pub fn new_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
4347        map_prefix_tuple_zeroed(Self::new_from_prefix(bytes))
4348    }
4349
4350    /// Constructs a new `Ref` from the suffix of a byte slice, zeroing the
4351    /// suffix.
4352    ///
4353    /// `new_from_suffix_zeroed` verifies that `bytes.len() >= size_of::<T>()`
4354    /// and that the last `size_of::<T>()` bytes of `bytes` are aligned to
4355    /// `align_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4356    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4357    /// caller. If either the length or alignment checks fail, it returns
4358    /// `None`.
4359    ///
4360    /// If the checks succeed, then the suffix which is consumed will be
4361    /// initialized to zero. This can be useful when re-using buffers to ensure
4362    /// that sensitive data previously stored in the buffer is not leaked.
4363    #[inline(always)]
4364    pub fn new_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
4365        map_suffix_tuple_zeroed(Self::new_from_suffix(bytes))
4366    }
4367}
4368
4369impl<B, T> Ref<B, [T]>
4370where
4371    B: ByteSliceMut,
4372{
4373    /// Constructs a new `Ref` of a slice type after zeroing the bytes.
4374    ///
4375    /// `new_slice_zeroed` verifies that `bytes.len()` is a multiple of
4376    /// `size_of::<T>()` and that `bytes` is aligned to `align_of::<T>()`, and
4377    /// constructs a new `Ref`. If either of these checks fail, it returns
4378    /// `None`.
4379    ///
4380    /// If the checks succeed, then `bytes` will be initialized to zero. This
4381    /// can be useful when re-using buffers to ensure that sensitive data
4382    /// previously stored in the buffer is not leaked.
4383    ///
4384    /// # Panics
4385    ///
4386    /// `new_slice` panics if `T` is a zero-sized type.
4387    #[inline(always)]
4388    pub fn new_slice_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
4389        map_zeroed(Self::new_slice(bytes))
4390    }
4391
4392    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice,
4393    /// after zeroing the bytes.
4394    ///
4395    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4396    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4397    /// first `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4398    /// and returns the remaining bytes to the caller. It also ensures that
4399    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4400    /// length, alignment, or overflow checks fail, it returns `None`.
4401    ///
4402    /// If the checks succeed, then the suffix which is consumed will be
4403    /// initialized to zero. This can be useful when re-using buffers to ensure
4404    /// that sensitive data previously stored in the buffer is not leaked.
4405    ///
4406    /// # Panics
4407    ///
4408    /// `new_slice_from_prefix_zeroed` panics if `T` is a zero-sized type.
4409    #[inline(always)]
4410    pub fn new_slice_from_prefix_zeroed(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4411        map_prefix_tuple_zeroed(Self::new_slice_from_prefix(bytes, count))
4412    }
4413
4414    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice,
4415    /// after zeroing the bytes.
4416    ///
4417    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4418    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4419    /// last `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4420    /// and returns the preceding bytes to the caller. It also ensures that
4421    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4422    /// length, alignment, or overflow checks fail, it returns `None`.
4423    ///
4424    /// If the checks succeed, then the consumed suffix will be initialized to
4425    /// zero. This can be useful when re-using buffers to ensure that sensitive
4426    /// data previously stored in the buffer is not leaked.
4427    ///
4428    /// # Panics
4429    ///
4430    /// `new_slice_from_suffix_zeroed` panics if `T` is a zero-sized type.
4431    #[inline(always)]
4432    pub fn new_slice_from_suffix_zeroed(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4433        map_suffix_tuple_zeroed(Self::new_slice_from_suffix(bytes, count))
4434    }
4435}
4436
4437impl<B, T> Ref<B, T>
4438where
4439    B: ByteSlice,
4440    T: Unaligned,
4441{
4442    /// Constructs a new `Ref` for a type with no alignment requirement.
4443    ///
4444    /// `new_unaligned` verifies that `bytes.len() == size_of::<T>()` and
4445    /// constructs a new `Ref`. If the check fails, it returns `None`.
4446    #[inline(always)]
4447    pub fn new_unaligned(bytes: B) -> Option<Ref<B, T>> {
4448        Ref::new(bytes)
4449    }
4450
4451    /// Constructs a new `Ref` from the prefix of a byte slice for a type with
4452    /// no alignment requirement.
4453    ///
4454    /// `new_unaligned_from_prefix` verifies that `bytes.len() >=
4455    /// size_of::<T>()`. It consumes the first `size_of::<T>()` bytes from
4456    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4457    /// caller. If the length check fails, it returns `None`.
4458    #[inline(always)]
4459    pub fn new_unaligned_from_prefix(bytes: B) -> Option<(Ref<B, T>, B)> {
4460        Ref::new_from_prefix(bytes)
4461    }
4462
4463    /// Constructs a new `Ref` from the suffix of a byte slice for a type with
4464    /// no alignment requirement.
4465    ///
4466    /// `new_unaligned_from_suffix` verifies that `bytes.len() >=
4467    /// size_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4468    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4469    /// caller. If the length check fails, it returns `None`.
4470    #[inline(always)]
4471    pub fn new_unaligned_from_suffix(bytes: B) -> Option<(B, Ref<B, T>)> {
4472        Ref::new_from_suffix(bytes)
4473    }
4474}
4475
4476impl<B, T> Ref<B, [T]>
4477where
4478    B: ByteSlice,
4479    T: Unaligned,
4480{
4481    /// Constructs a new `Ref` of a slice type with no alignment requirement.
4482    ///
4483    /// `new_slice_unaligned` verifies that `bytes.len()` is a multiple of
4484    /// `size_of::<T>()` and constructs a new `Ref`. If the check fails, it
4485    /// returns `None`.
4486    ///
4487    /// # Panics
4488    ///
4489    /// `new_slice` panics if `T` is a zero-sized type.
4490    #[inline(always)]
4491    pub fn new_slice_unaligned(bytes: B) -> Option<Ref<B, [T]>> {
4492        Ref::new_slice(bytes)
4493    }
4494
4495    /// Constructs a new `Ref` of a slice type with no alignment requirement
4496    /// from the prefix of a byte slice.
4497    ///
4498    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4499    /// count`. It consumes the first `size_of::<T>() * count` bytes from
4500    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4501    /// caller. It also ensures that `sizeof::<T>() * count` does not overflow a
4502    /// `usize`. If either the length, or overflow checks fail, it returns
4503    /// `None`.
4504    ///
4505    /// # Panics
4506    ///
4507    /// `new_slice_unaligned_from_prefix` panics if `T` is a zero-sized type.
4508    #[inline(always)]
4509    pub fn new_slice_unaligned_from_prefix(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4510        Ref::new_slice_from_prefix(bytes, count)
4511    }
4512
4513    /// Constructs a new `Ref` of a slice type with no alignment requirement
4514    /// from the suffix of a byte slice.
4515    ///
4516    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4517    /// count`. It consumes the last `size_of::<T>() * count` bytes from `bytes`
4518    /// to construct a `Ref`, and returns the remaining bytes to the caller. It
4519    /// also ensures that `sizeof::<T>() * count` does not overflow a `usize`.
4520    /// If either the length, or overflow checks fail, it returns `None`.
4521    ///
4522    /// # Panics
4523    ///
4524    /// `new_slice_unaligned_from_suffix` panics if `T` is a zero-sized type.
4525    #[inline(always)]
4526    pub fn new_slice_unaligned_from_suffix(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4527        Ref::new_slice_from_suffix(bytes, count)
4528    }
4529}
4530
4531impl<B, T> Ref<B, T>
4532where
4533    B: ByteSliceMut,
4534    T: Unaligned,
4535{
4536    /// Constructs a new `Ref` for a type with no alignment requirement, zeroing
4537    /// the bytes.
4538    ///
4539    /// `new_unaligned_zeroed` verifies that `bytes.len() == size_of::<T>()` and
4540    /// constructs a new `Ref`. If the check fails, it returns `None`.
4541    ///
4542    /// If the check succeeds, then `bytes` will be initialized to zero. This
4543    /// can be useful when re-using buffers to ensure that sensitive data
4544    /// previously stored in the buffer is not leaked.
4545    #[inline(always)]
4546    pub fn new_unaligned_zeroed(bytes: B) -> Option<Ref<B, T>> {
4547        map_zeroed(Self::new_unaligned(bytes))
4548    }
4549
4550    /// Constructs a new `Ref` from the prefix of a byte slice for a type with
4551    /// no alignment requirement, zeroing the prefix.
4552    ///
4553    /// `new_unaligned_from_prefix_zeroed` verifies that `bytes.len() >=
4554    /// size_of::<T>()`. It consumes the first `size_of::<T>()` bytes from
4555    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4556    /// caller. If the length check fails, it returns `None`.
4557    ///
4558    /// If the check succeeds, then the prefix which is consumed will be
4559    /// initialized to zero. This can be useful when re-using buffers to ensure
4560    /// that sensitive data previously stored in the buffer is not leaked.
4561    #[inline(always)]
4562    pub fn new_unaligned_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
4563        map_prefix_tuple_zeroed(Self::new_unaligned_from_prefix(bytes))
4564    }
4565
4566    /// Constructs a new `Ref` from the suffix of a byte slice for a type with
4567    /// no alignment requirement, zeroing the suffix.
4568    ///
4569    /// `new_unaligned_from_suffix_zeroed` verifies that `bytes.len() >=
4570    /// size_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4571    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4572    /// caller. If the length check fails, it returns `None`.
4573    ///
4574    /// If the check succeeds, then the suffix which is consumed will be
4575    /// initialized to zero. This can be useful when re-using buffers to ensure
4576    /// that sensitive data previously stored in the buffer is not leaked.
4577    #[inline(always)]
4578    pub fn new_unaligned_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
4579        map_suffix_tuple_zeroed(Self::new_unaligned_from_suffix(bytes))
4580    }
4581}
4582
4583impl<B, T> Ref<B, [T]>
4584where
4585    B: ByteSliceMut,
4586    T: Unaligned,
4587{
4588    /// Constructs a new `Ref` for a slice type with no alignment requirement,
4589    /// zeroing the bytes.
4590    ///
4591    /// `new_slice_unaligned_zeroed` verifies that `bytes.len()` is a multiple
4592    /// of `size_of::<T>()` and constructs a new `Ref`. If the check fails, it
4593    /// returns `None`.
4594    ///
4595    /// If the check succeeds, then `bytes` will be initialized to zero. This
4596    /// can be useful when re-using buffers to ensure that sensitive data
4597    /// previously stored in the buffer is not leaked.
4598    ///
4599    /// # Panics
4600    ///
4601    /// `new_slice` panics if `T` is a zero-sized type.
4602    #[inline(always)]
4603    pub fn new_slice_unaligned_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
4604        map_zeroed(Self::new_slice_unaligned(bytes))
4605    }
4606
4607    /// Constructs a new `Ref` of a slice type with no alignment requirement
4608    /// from the prefix of a byte slice, after zeroing the bytes.
4609    ///
4610    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4611    /// count`. It consumes the first `size_of::<T>() * count` bytes from
4612    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4613    /// caller. It also ensures that `sizeof::<T>() * count` does not overflow a
4614    /// `usize`. If either the length, or overflow checks fail, it returns
4615    /// `None`.
4616    ///
4617    /// If the checks succeed, then the prefix will be initialized to zero. This
4618    /// can be useful when re-using buffers to ensure that sensitive data
4619    /// previously stored in the buffer is not leaked.
4620    ///
4621    /// # Panics
4622    ///
4623    /// `new_slice_unaligned_from_prefix_zeroed` panics if `T` is a zero-sized
4624    /// type.
4625    #[inline(always)]
4626    pub fn new_slice_unaligned_from_prefix_zeroed(
4627        bytes: B,
4628        count: usize,
4629    ) -> Option<(Ref<B, [T]>, B)> {
4630        map_prefix_tuple_zeroed(Self::new_slice_unaligned_from_prefix(bytes, count))
4631    }
4632
4633    /// Constructs a new `Ref` of a slice type with no alignment requirement
4634    /// from the suffix of a byte slice, after zeroing the bytes.
4635    ///
4636    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4637    /// count`. It consumes the last `size_of::<T>() * count` bytes from `bytes`
4638    /// to construct a `Ref`, and returns the remaining bytes to the caller. It
4639    /// also ensures that `sizeof::<T>() * count` does not overflow a `usize`.
4640    /// If either the length, or overflow checks fail, it returns `None`.
4641    ///
4642    /// If the checks succeed, then the suffix will be initialized to zero. This
4643    /// can be useful when re-using buffers to ensure that sensitive data
4644    /// previously stored in the buffer is not leaked.
4645    ///
4646    /// # Panics
4647    ///
4648    /// `new_slice_unaligned_from_suffix_zeroed` panics if `T` is a zero-sized
4649    /// type.
4650    #[inline(always)]
4651    pub fn new_slice_unaligned_from_suffix_zeroed(
4652        bytes: B,
4653        count: usize,
4654    ) -> Option<(B, Ref<B, [T]>)> {
4655        map_suffix_tuple_zeroed(Self::new_slice_unaligned_from_suffix(bytes, count))
4656    }
4657}
4658
4659impl<'a, B, T> Ref<B, T>
4660where
4661    B: 'a + ByteSlice,
4662    T: FromBytes,
4663{
4664    /// Converts this `Ref` into a reference.
4665    ///
4666    /// `into_ref` consumes the `Ref`, and returns a reference to `T`.
4667    #[inline(always)]
4668    pub fn into_ref(self) -> &'a T {
4669        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4670
4671        // SAFETY: According to the safety preconditions on
4672        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4673        // ensures that, given `B: 'a`, it is sound to drop `self` and still
4674        // access the underlying memory using reads for `'a`.
4675        unsafe { self.deref_helper() }
4676    }
4677}
4678
4679impl<'a, B, T> Ref<B, T>
4680where
4681    B: 'a + ByteSliceMut,
4682    T: FromBytes + AsBytes,
4683{
4684    /// Converts this `Ref` into a mutable reference.
4685    ///
4686    /// `into_mut` consumes the `Ref`, and returns a mutable reference to `T`.
4687    #[inline(always)]
4688    pub fn into_mut(mut self) -> &'a mut T {
4689        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4690
4691        // SAFETY: According to the safety preconditions on
4692        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4693        // ensures that, given `B: 'a + ByteSliceMut`, it is sound to drop
4694        // `self` and still access the underlying memory using both reads and
4695        // writes for `'a`.
4696        unsafe { self.deref_mut_helper() }
4697    }
4698}
4699
4700impl<'a, B, T> Ref<B, [T]>
4701where
4702    B: 'a + ByteSlice,
4703    T: FromBytes,
4704{
4705    /// Converts this `Ref` into a slice reference.
4706    ///
4707    /// `into_slice` consumes the `Ref`, and returns a reference to `[T]`.
4708    #[inline(always)]
4709    pub fn into_slice(self) -> &'a [T] {
4710        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4711
4712        // SAFETY: According to the safety preconditions on
4713        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4714        // ensures that, given `B: 'a`, it is sound to drop `self` and still
4715        // access the underlying memory using reads for `'a`.
4716        unsafe { self.deref_slice_helper() }
4717    }
4718}
4719
4720impl<'a, B, T> Ref<B, [T]>
4721where
4722    B: 'a + ByteSliceMut,
4723    T: FromBytes + AsBytes,
4724{
4725    /// Converts this `Ref` into a mutable slice reference.
4726    ///
4727    /// `into_mut_slice` consumes the `Ref`, and returns a mutable reference to
4728    /// `[T]`.
4729    #[inline(always)]
4730    pub fn into_mut_slice(mut self) -> &'a mut [T] {
4731        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4732
4733        // SAFETY: According to the safety preconditions on
4734        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4735        // ensures that, given `B: 'a + ByteSliceMut`, it is sound to drop
4736        // `self` and still access the underlying memory using both reads and
4737        // writes for `'a`.
4738        unsafe { self.deref_mut_slice_helper() }
4739    }
4740}
4741
4742impl<B, T> Ref<B, T>
4743where
4744    B: ByteSlice,
4745    T: FromBytes,
4746{
4747    /// Creates an immutable reference to `T` with a specific lifetime.
4748    ///
4749    /// # Safety
4750    ///
4751    /// The type bounds on this method guarantee that it is safe to create an
4752    /// immutable reference to `T` from `self`. However, since the lifetime `'a`
4753    /// is not required to be shorter than the lifetime of the reference to
4754    /// `self`, the caller must guarantee that the lifetime `'a` is valid for
4755    /// this reference. In particular, the referent must exist for all of `'a`,
4756    /// and no mutable references to the same memory may be constructed during
4757    /// `'a`.
4758    unsafe fn deref_helper<'a>(&self) -> &'a T {
4759        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4760        #[allow(clippy::undocumented_unsafe_blocks)]
4761        unsafe {
4762            &*self.0.as_ptr().cast::<T>()
4763        }
4764    }
4765}
4766
4767impl<B, T> Ref<B, T>
4768where
4769    B: ByteSliceMut,
4770    T: FromBytes + AsBytes,
4771{
4772    /// Creates a mutable reference to `T` with a specific lifetime.
4773    ///
4774    /// # Safety
4775    ///
4776    /// The type bounds on this method guarantee that it is safe to create a
4777    /// mutable reference to `T` from `self`. However, since the lifetime `'a`
4778    /// is not required to be shorter than the lifetime of the reference to
4779    /// `self`, the caller must guarantee that the lifetime `'a` is valid for
4780    /// this reference. In particular, the referent must exist for all of `'a`,
4781    /// and no other references - mutable or immutable - to the same memory may
4782    /// be constructed during `'a`.
4783    unsafe fn deref_mut_helper<'a>(&mut self) -> &'a mut T {
4784        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4785        #[allow(clippy::undocumented_unsafe_blocks)]
4786        unsafe {
4787            &mut *self.0.as_mut_ptr().cast::<T>()
4788        }
4789    }
4790}
4791
4792impl<B, T> Ref<B, [T]>
4793where
4794    B: ByteSlice,
4795    T: FromBytes,
4796{
4797    /// Creates an immutable reference to `[T]` with a specific lifetime.
4798    ///
4799    /// # Safety
4800    ///
4801    /// `deref_slice_helper` has the same safety requirements as `deref_helper`.
4802    unsafe fn deref_slice_helper<'a>(&self) -> &'a [T] {
4803        let len = self.0.len();
4804        let elem_size = mem::size_of::<T>();
4805        debug_assert_ne!(elem_size, 0);
4806        // `Ref<_, [T]>` maintains the invariant that `size_of::<T>() > 0`.
4807        // Thus, neither the mod nor division operations here can panic.
4808        #[allow(clippy::arithmetic_side_effects)]
4809        let elems = {
4810            debug_assert_eq!(len % elem_size, 0);
4811            len / elem_size
4812        };
4813        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4814        #[allow(clippy::undocumented_unsafe_blocks)]
4815        unsafe {
4816            slice::from_raw_parts(self.0.as_ptr().cast::<T>(), elems)
4817        }
4818    }
4819}
4820
4821impl<B, T> Ref<B, [T]>
4822where
4823    B: ByteSliceMut,
4824    T: FromBytes + AsBytes,
4825{
4826    /// Creates a mutable reference to `[T]` with a specific lifetime.
4827    ///
4828    /// # Safety
4829    ///
4830    /// `deref_mut_slice_helper` has the same safety requirements as
4831    /// `deref_mut_helper`.
4832    unsafe fn deref_mut_slice_helper<'a>(&mut self) -> &'a mut [T] {
4833        let len = self.0.len();
4834        let elem_size = mem::size_of::<T>();
4835        debug_assert_ne!(elem_size, 0);
4836        // `Ref<_, [T]>` maintains the invariant that `size_of::<T>() > 0`.
4837        // Thus, neither the mod nor division operations here can panic.
4838        #[allow(clippy::arithmetic_side_effects)]
4839        let elems = {
4840            debug_assert_eq!(len % elem_size, 0);
4841            len / elem_size
4842        };
4843        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4844        #[allow(clippy::undocumented_unsafe_blocks)]
4845        unsafe {
4846            slice::from_raw_parts_mut(self.0.as_mut_ptr().cast::<T>(), elems)
4847        }
4848    }
4849}
4850
4851impl<B, T> Ref<B, T>
4852where
4853    B: ByteSlice,
4854    T: ?Sized,
4855{
4856    /// Gets the underlying bytes.
4857    #[inline]
4858    pub fn bytes(&self) -> &[u8] {
4859        &self.0
4860    }
4861}
4862
4863impl<B, T> Ref<B, T>
4864where
4865    B: ByteSliceMut,
4866    T: ?Sized,
4867{
4868    /// Gets the underlying bytes mutably.
4869    #[inline]
4870    pub fn bytes_mut(&mut self) -> &mut [u8] {
4871        &mut self.0
4872    }
4873}
4874
4875impl<B, T> Ref<B, T>
4876where
4877    B: ByteSlice,
4878    T: FromBytes,
4879{
4880    /// Reads a copy of `T`.
4881    #[inline]
4882    pub fn read(&self) -> T {
4883        // SAFETY: Because of the invariants on `Ref`, we know that `self.0` is
4884        // at least `size_of::<T>()` bytes long, and that it is at least as
4885        // aligned as `align_of::<T>()`. Because `T: FromBytes`, it is sound to
4886        // interpret these bytes as a `T`.
4887        unsafe { ptr::read(self.0.as_ptr().cast::<T>()) }
4888    }
4889}
4890
4891impl<B, T> Ref<B, T>
4892where
4893    B: ByteSliceMut,
4894    T: AsBytes,
4895{
4896    /// Writes the bytes of `t` and then forgets `t`.
4897    #[inline]
4898    pub fn write(&mut self, t: T) {
4899        // SAFETY: Because of the invariants on `Ref`, we know that `self.0` is
4900        // at least `size_of::<T>()` bytes long, and that it is at least as
4901        // aligned as `align_of::<T>()`. Writing `t` to the buffer will allow
4902        // all of the bytes of `t` to be accessed as a `[u8]`, but because `T:
4903        // AsBytes`, we know this is sound.
4904        unsafe { ptr::write(self.0.as_mut_ptr().cast::<T>(), t) }
4905    }
4906}
4907
4908impl<B, T> Deref for Ref<B, T>
4909where
4910    B: ByteSlice,
4911    T: FromBytes,
4912{
4913    type Target = T;
4914    #[inline]
4915    fn deref(&self) -> &T {
4916        // SAFETY: This is sound because the lifetime of `self` is the same as
4917        // the lifetime of the return value, meaning that a) the returned
4918        // reference cannot outlive `self` and, b) no mutable methods on `self`
4919        // can be called during the lifetime of the returned reference. See the
4920        // documentation on `deref_helper` for what invariants we are required
4921        // to uphold.
4922        unsafe { self.deref_helper() }
4923    }
4924}
4925
4926impl<B, T> DerefMut for Ref<B, T>
4927where
4928    B: ByteSliceMut,
4929    T: FromBytes + AsBytes,
4930{
4931    #[inline]
4932    fn deref_mut(&mut self) -> &mut T {
4933        // SAFETY: This is sound because the lifetime of `self` is the same as
4934        // the lifetime of the return value, meaning that a) the returned
4935        // reference cannot outlive `self` and, b) no other methods on `self`
4936        // can be called during the lifetime of the returned reference. See the
4937        // documentation on `deref_mut_helper` for what invariants we are
4938        // required to uphold.
4939        unsafe { self.deref_mut_helper() }
4940    }
4941}
4942
4943impl<B, T> Deref for Ref<B, [T]>
4944where
4945    B: ByteSlice,
4946    T: FromBytes,
4947{
4948    type Target = [T];
4949    #[inline]
4950    fn deref(&self) -> &[T] {
4951        // SAFETY: This is sound because the lifetime of `self` is the same as
4952        // the lifetime of the return value, meaning that a) the returned
4953        // reference cannot outlive `self` and, b) no mutable methods on `self`
4954        // can be called during the lifetime of the returned reference. See the
4955        // documentation on `deref_slice_helper` for what invariants we are
4956        // required to uphold.
4957        unsafe { self.deref_slice_helper() }
4958    }
4959}
4960
4961impl<B, T> DerefMut for Ref<B, [T]>
4962where
4963    B: ByteSliceMut,
4964    T: FromBytes + AsBytes,
4965{
4966    #[inline]
4967    fn deref_mut(&mut self) -> &mut [T] {
4968        // SAFETY: This is sound because the lifetime of `self` is the same as
4969        // the lifetime of the return value, meaning that a) the returned
4970        // reference cannot outlive `self` and, b) no other methods on `self`
4971        // can be called during the lifetime of the returned reference. See the
4972        // documentation on `deref_mut_slice_helper` for what invariants we are
4973        // required to uphold.
4974        unsafe { self.deref_mut_slice_helper() }
4975    }
4976}
4977
4978impl<T, B> Display for Ref<B, T>
4979where
4980    B: ByteSlice,
4981    T: FromBytes + Display,
4982{
4983    #[inline]
4984    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
4985        let inner: &T = self;
4986        inner.fmt(fmt)
4987    }
4988}
4989
4990impl<T, B> Display for Ref<B, [T]>
4991where
4992    B: ByteSlice,
4993    T: FromBytes,
4994    [T]: Display,
4995{
4996    #[inline]
4997    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
4998        let inner: &[T] = self;
4999        inner.fmt(fmt)
5000    }
5001}
5002
5003impl<T, B> Debug for Ref<B, T>
5004where
5005    B: ByteSlice,
5006    T: FromBytes + Debug,
5007{
5008    #[inline]
5009    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
5010        let inner: &T = self;
5011        fmt.debug_tuple("Ref").field(&inner).finish()
5012    }
5013}
5014
5015impl<T, B> Debug for Ref<B, [T]>
5016where
5017    B: ByteSlice,
5018    T: FromBytes + Debug,
5019{
5020    #[inline]
5021    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
5022        let inner: &[T] = self;
5023        fmt.debug_tuple("Ref").field(&inner).finish()
5024    }
5025}
5026
5027impl<T, B> Eq for Ref<B, T>
5028where
5029    B: ByteSlice,
5030    T: FromBytes + Eq,
5031{
5032}
5033
5034impl<T, B> Eq for Ref<B, [T]>
5035where
5036    B: ByteSlice,
5037    T: FromBytes + Eq,
5038{
5039}
5040
5041impl<T, B> PartialEq for Ref<B, T>
5042where
5043    B: ByteSlice,
5044    T: FromBytes + PartialEq,
5045{
5046    #[inline]
5047    fn eq(&self, other: &Self) -> bool {
5048        self.deref().eq(other.deref())
5049    }
5050}
5051
5052impl<T, B> PartialEq for Ref<B, [T]>
5053where
5054    B: ByteSlice,
5055    T: FromBytes + PartialEq,
5056{
5057    #[inline]
5058    fn eq(&self, other: &Self) -> bool {
5059        self.deref().eq(other.deref())
5060    }
5061}
5062
5063impl<T, B> Ord for Ref<B, T>
5064where
5065    B: ByteSlice,
5066    T: FromBytes + Ord,
5067{
5068    #[inline]
5069    fn cmp(&self, other: &Self) -> Ordering {
5070        let inner: &T = self;
5071        let other_inner: &T = other;
5072        inner.cmp(other_inner)
5073    }
5074}
5075
5076impl<T, B> Ord for Ref<B, [T]>
5077where
5078    B: ByteSlice,
5079    T: FromBytes + Ord,
5080{
5081    #[inline]
5082    fn cmp(&self, other: &Self) -> Ordering {
5083        let inner: &[T] = self;
5084        let other_inner: &[T] = other;
5085        inner.cmp(other_inner)
5086    }
5087}
5088
5089impl<T, B> PartialOrd for Ref<B, T>
5090where
5091    B: ByteSlice,
5092    T: FromBytes + PartialOrd,
5093{
5094    #[inline]
5095    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
5096        let inner: &T = self;
5097        let other_inner: &T = other;
5098        inner.partial_cmp(other_inner)
5099    }
5100}
5101
5102impl<T, B> PartialOrd for Ref<B, [T]>
5103where
5104    B: ByteSlice,
5105    T: FromBytes + PartialOrd,
5106{
5107    #[inline]
5108    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
5109        let inner: &[T] = self;
5110        let other_inner: &[T] = other;
5111        inner.partial_cmp(other_inner)
5112    }
5113}
5114
5115mod sealed {
5116    pub trait ByteSliceSealed {}
5117}
5118
5119// ByteSlice and ByteSliceMut abstract over [u8] references (&[u8], &mut [u8],
5120// Ref<[u8]>, RefMut<[u8]>, etc). We rely on various behaviors of these
5121// references such as that a given reference will never changes its length
5122// between calls to deref() or deref_mut(), and that split_at() works as
5123// expected. If ByteSlice or ByteSliceMut were not sealed, consumers could
5124// implement them in a way that violated these behaviors, and would break our
5125// unsafe code. Thus, we seal them and implement it only for known-good
5126// reference types. For the same reason, they're unsafe traits.
5127
5128#[allow(clippy::missing_safety_doc)] // TODO(fxbug.dev/99068)
5129/// A mutable or immutable reference to a byte slice.
5130///
5131/// `ByteSlice` abstracts over the mutability of a byte slice reference, and is
5132/// implemented for various special reference types such as `Ref<[u8]>` and
5133/// `RefMut<[u8]>`.
5134///
5135/// Note that, while it would be technically possible, `ByteSlice` is not
5136/// implemented for [`Vec<u8>`], as the only way to implement the [`split_at`]
5137/// method would involve reallocation, and `split_at` must be a very cheap
5138/// operation in order for the utilities in this crate to perform as designed.
5139///
5140/// [`split_at`]: crate::ByteSlice::split_at
5141// It may seem overkill to go to this length to ensure that this doc link never
5142// breaks. We do this because it simplifies CI - it means that generating docs
5143// always succeeds, so we don't need special logic to only generate docs under
5144// certain features.
5145#[cfg_attr(feature = "alloc", doc = "[`Vec<u8>`]: alloc::vec::Vec")]
5146#[cfg_attr(
5147    not(feature = "alloc"),
5148    doc = "[`Vec<u8>`]: https://doc.rust-lang.org/std/vec/struct.Vec.html"
5149)]
5150pub unsafe trait ByteSlice: Deref<Target = [u8]> + Sized + sealed::ByteSliceSealed {
5151    /// Are the [`Ref::into_ref`] and [`Ref::into_mut`] methods sound when used
5152    /// with `Self`? If not, evaluating this constant must panic at compile
5153    /// time.
5154    ///
5155    /// This exists to work around #716 on versions of zerocopy prior to 0.8.
5156    ///
5157    /// # Safety
5158    ///
5159    /// This may only be set to true if the following holds: Given the
5160    /// following:
5161    /// - `Self: 'a`
5162    /// - `bytes: Self`
5163    /// - `let ptr = bytes.as_ptr()`
5164    ///
5165    /// ...then:
5166    /// - Using `ptr` to read the memory previously addressed by `bytes` is
5167    ///   sound for `'a` even after `bytes` has been dropped.
5168    /// - If `Self: ByteSliceMut`, using `ptr` to write the memory previously
5169    ///   addressed by `bytes` is sound for `'a` even after `bytes` has been
5170    ///   dropped.
5171    #[doc(hidden)]
5172    const INTO_REF_INTO_MUT_ARE_SOUND: bool;
5173
5174    /// Gets a raw pointer to the first byte in the slice.
5175    #[inline]
5176    fn as_ptr(&self) -> *const u8 {
5177        <[u8]>::as_ptr(self)
5178    }
5179
5180    /// Splits the slice at the midpoint.
5181    ///
5182    /// `x.split_at(mid)` returns `x[..mid]` and `x[mid..]`.
5183    ///
5184    /// # Panics
5185    ///
5186    /// `x.split_at(mid)` panics if `mid > x.len()`.
5187    fn split_at(self, mid: usize) -> (Self, Self);
5188}
5189
5190#[allow(clippy::missing_safety_doc)] // TODO(fxbug.dev/99068)
5191/// A mutable reference to a byte slice.
5192///
5193/// `ByteSliceMut` abstracts over various ways of storing a mutable reference to
5194/// a byte slice, and is implemented for various special reference types such as
5195/// `RefMut<[u8]>`.
5196pub unsafe trait ByteSliceMut: ByteSlice + DerefMut {
5197    /// Gets a mutable raw pointer to the first byte in the slice.
5198    #[inline]
5199    fn as_mut_ptr(&mut self) -> *mut u8 {
5200        <[u8]>::as_mut_ptr(self)
5201    }
5202}
5203
5204impl<'a> sealed::ByteSliceSealed for &'a [u8] {}
5205// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5206#[allow(clippy::undocumented_unsafe_blocks)]
5207unsafe impl<'a> ByteSlice for &'a [u8] {
5208    // SAFETY: If `&'b [u8]: 'a`, then the underlying memory is treated as
5209    // borrowed immutably for `'a` even if the slice itself is dropped.
5210    const INTO_REF_INTO_MUT_ARE_SOUND: bool = true;
5211
5212    #[inline]
5213    fn split_at(self, mid: usize) -> (Self, Self) {
5214        <[u8]>::split_at(self, mid)
5215    }
5216}
5217
5218impl<'a> sealed::ByteSliceSealed for &'a mut [u8] {}
5219// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5220#[allow(clippy::undocumented_unsafe_blocks)]
5221unsafe impl<'a> ByteSlice for &'a mut [u8] {
5222    // SAFETY: If `&'b mut [u8]: 'a`, then the underlying memory is treated as
5223    // borrowed mutably for `'a` even if the slice itself is dropped.
5224    const INTO_REF_INTO_MUT_ARE_SOUND: bool = true;
5225
5226    #[inline]
5227    fn split_at(self, mid: usize) -> (Self, Self) {
5228        <[u8]>::split_at_mut(self, mid)
5229    }
5230}
5231
5232impl<'a> sealed::ByteSliceSealed for cell::Ref<'a, [u8]> {}
5233// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5234#[allow(clippy::undocumented_unsafe_blocks)]
5235unsafe impl<'a> ByteSlice for cell::Ref<'a, [u8]> {
5236    const INTO_REF_INTO_MUT_ARE_SOUND: bool = if !cfg!(doc) {
5237        panic!("Ref::into_ref and Ref::into_mut are unsound when used with core::cell::Ref; see https://github.com/google/zerocopy/issues/716")
5238    } else {
5239        // When compiling documentation, allow the evaluation of this constant
5240        // to succeed. This doesn't represent a soundness hole - it just delays
5241        // any error to runtime. The reason we need this is that, otherwise,
5242        // `rustdoc` will fail when trying to document this item.
5243        false
5244    };
5245
5246    #[inline]
5247    fn split_at(self, mid: usize) -> (Self, Self) {
5248        cell::Ref::map_split(self, |slice| <[u8]>::split_at(slice, mid))
5249    }
5250}
5251
5252impl<'a> sealed::ByteSliceSealed for RefMut<'a, [u8]> {}
5253// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5254#[allow(clippy::undocumented_unsafe_blocks)]
5255unsafe impl<'a> ByteSlice for RefMut<'a, [u8]> {
5256    const INTO_REF_INTO_MUT_ARE_SOUND: bool = if !cfg!(doc) {
5257        panic!("Ref::into_ref and Ref::into_mut are unsound when used with core::cell::RefMut; see https://github.com/google/zerocopy/issues/716")
5258    } else {
5259        // When compiling documentation, allow the evaluation of this constant
5260        // to succeed. This doesn't represent a soundness hole - it just delays
5261        // any error to runtime. The reason we need this is that, otherwise,
5262        // `rustdoc` will fail when trying to document this item.
5263        false
5264    };
5265
5266    #[inline]
5267    fn split_at(self, mid: usize) -> (Self, Self) {
5268        RefMut::map_split(self, |slice| <[u8]>::split_at_mut(slice, mid))
5269    }
5270}
5271
5272// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5273#[allow(clippy::undocumented_unsafe_blocks)]
5274unsafe impl<'a> ByteSliceMut for &'a mut [u8] {}
5275
5276// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5277#[allow(clippy::undocumented_unsafe_blocks)]
5278unsafe impl<'a> ByteSliceMut for RefMut<'a, [u8]> {}
5279
5280#[cfg(feature = "alloc")]
5281#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
5282mod alloc_support {
5283    use alloc::vec::Vec;
5284
5285    use super::*;
5286
5287    /// Extends a `Vec<T>` by pushing `additional` new items onto the end of the
5288    /// vector. The new items are initialized with zeroes.
5289    ///
5290    /// # Panics
5291    ///
5292    /// Panics if `Vec::reserve(additional)` fails to reserve enough memory.
5293    #[inline(always)]
5294    pub fn extend_vec_zeroed<T: FromZeroes>(v: &mut Vec<T>, additional: usize) {
5295        insert_vec_zeroed(v, v.len(), additional);
5296    }
5297
5298    /// Inserts `additional` new items into `Vec<T>` at `position`.
5299    /// The new items are initialized with zeroes.
5300    ///
5301    /// # Panics
5302    ///
5303    /// * Panics if `position > v.len()`.
5304    /// * Panics if `Vec::reserve(additional)` fails to reserve enough memory.
5305    #[inline]
5306    pub fn insert_vec_zeroed<T: FromZeroes>(v: &mut Vec<T>, position: usize, additional: usize) {
5307        assert!(position <= v.len());
5308        v.reserve(additional);
5309        // SAFETY: The `reserve` call guarantees that these cannot overflow:
5310        // * `ptr.add(position)`
5311        // * `position + additional`
5312        // * `v.len() + additional`
5313        //
5314        // `v.len() - position` cannot overflow because we asserted that
5315        // `position <= v.len()`.
5316        unsafe {
5317            // This is a potentially overlapping copy.
5318            let ptr = v.as_mut_ptr();
5319            #[allow(clippy::arithmetic_side_effects)]
5320            ptr.add(position).copy_to(ptr.add(position + additional), v.len() - position);
5321            ptr.add(position).write_bytes(0, additional);
5322            #[allow(clippy::arithmetic_side_effects)]
5323            v.set_len(v.len() + additional);
5324        }
5325    }
5326
5327    #[cfg(test)]
5328    mod tests {
5329        use core::convert::TryFrom as _;
5330
5331        use super::*;
5332
5333        #[test]
5334        fn test_extend_vec_zeroed() {
5335            // Test extending when there is an existing allocation.
5336            let mut v = vec![100u64, 200, 300];
5337            extend_vec_zeroed(&mut v, 3);
5338            assert_eq!(v.len(), 6);
5339            assert_eq!(&*v, &[100, 200, 300, 0, 0, 0]);
5340            drop(v);
5341
5342            // Test extending when there is no existing allocation.
5343            let mut v: Vec<u64> = Vec::new();
5344            extend_vec_zeroed(&mut v, 3);
5345            assert_eq!(v.len(), 3);
5346            assert_eq!(&*v, &[0, 0, 0]);
5347            drop(v);
5348        }
5349
5350        #[test]
5351        fn test_extend_vec_zeroed_zst() {
5352            // Test extending when there is an existing (fake) allocation.
5353            let mut v = vec![(), (), ()];
5354            extend_vec_zeroed(&mut v, 3);
5355            assert_eq!(v.len(), 6);
5356            assert_eq!(&*v, &[(), (), (), (), (), ()]);
5357            drop(v);
5358
5359            // Test extending when there is no existing (fake) allocation.
5360            let mut v: Vec<()> = Vec::new();
5361            extend_vec_zeroed(&mut v, 3);
5362            assert_eq!(&*v, &[(), (), ()]);
5363            drop(v);
5364        }
5365
5366        #[test]
5367        fn test_insert_vec_zeroed() {
5368            // Insert at start (no existing allocation).
5369            let mut v: Vec<u64> = Vec::new();
5370            insert_vec_zeroed(&mut v, 0, 2);
5371            assert_eq!(v.len(), 2);
5372            assert_eq!(&*v, &[0, 0]);
5373            drop(v);
5374
5375            // Insert at start.
5376            let mut v = vec![100u64, 200, 300];
5377            insert_vec_zeroed(&mut v, 0, 2);
5378            assert_eq!(v.len(), 5);
5379            assert_eq!(&*v, &[0, 0, 100, 200, 300]);
5380            drop(v);
5381
5382            // Insert at middle.
5383            let mut v = vec![100u64, 200, 300];
5384            insert_vec_zeroed(&mut v, 1, 1);
5385            assert_eq!(v.len(), 4);
5386            assert_eq!(&*v, &[100, 0, 200, 300]);
5387            drop(v);
5388
5389            // Insert at end.
5390            let mut v = vec![100u64, 200, 300];
5391            insert_vec_zeroed(&mut v, 3, 1);
5392            assert_eq!(v.len(), 4);
5393            assert_eq!(&*v, &[100, 200, 300, 0]);
5394            drop(v);
5395        }
5396
5397        #[test]
5398        fn test_insert_vec_zeroed_zst() {
5399            // Insert at start (no existing fake allocation).
5400            let mut v: Vec<()> = Vec::new();
5401            insert_vec_zeroed(&mut v, 0, 2);
5402            assert_eq!(v.len(), 2);
5403            assert_eq!(&*v, &[(), ()]);
5404            drop(v);
5405
5406            // Insert at start.
5407            let mut v = vec![(), (), ()];
5408            insert_vec_zeroed(&mut v, 0, 2);
5409            assert_eq!(v.len(), 5);
5410            assert_eq!(&*v, &[(), (), (), (), ()]);
5411            drop(v);
5412
5413            // Insert at middle.
5414            let mut v = vec![(), (), ()];
5415            insert_vec_zeroed(&mut v, 1, 1);
5416            assert_eq!(v.len(), 4);
5417            assert_eq!(&*v, &[(), (), (), ()]);
5418            drop(v);
5419
5420            // Insert at end.
5421            let mut v = vec![(), (), ()];
5422            insert_vec_zeroed(&mut v, 3, 1);
5423            assert_eq!(v.len(), 4);
5424            assert_eq!(&*v, &[(), (), (), ()]);
5425            drop(v);
5426        }
5427
5428        #[test]
5429        fn test_new_box_zeroed() {
5430            assert_eq!(*u64::new_box_zeroed(), 0);
5431        }
5432
5433        #[test]
5434        fn test_new_box_zeroed_array() {
5435            drop(<[u32; 0x1000]>::new_box_zeroed());
5436        }
5437
5438        #[test]
5439        fn test_new_box_zeroed_zst() {
5440            // This test exists in order to exercise unsafe code, especially
5441            // when running under Miri.
5442            #[allow(clippy::unit_cmp)]
5443            {
5444                assert_eq!(*<()>::new_box_zeroed(), ());
5445            }
5446        }
5447
5448        #[test]
5449        fn test_new_box_slice_zeroed() {
5450            let mut s: Box<[u64]> = u64::new_box_slice_zeroed(3);
5451            assert_eq!(s.len(), 3);
5452            assert_eq!(&*s, &[0, 0, 0]);
5453            s[1] = 3;
5454            assert_eq!(&*s, &[0, 3, 0]);
5455        }
5456
5457        #[test]
5458        fn test_new_box_slice_zeroed_empty() {
5459            let s: Box<[u64]> = u64::new_box_slice_zeroed(0);
5460            assert_eq!(s.len(), 0);
5461        }
5462
5463        #[test]
5464        fn test_new_box_slice_zeroed_zst() {
5465            let mut s: Box<[()]> = <()>::new_box_slice_zeroed(3);
5466            assert_eq!(s.len(), 3);
5467            assert!(s.get(10).is_none());
5468            // This test exists in order to exercise unsafe code, especially
5469            // when running under Miri.
5470            #[allow(clippy::unit_cmp)]
5471            {
5472                assert_eq!(s[1], ());
5473            }
5474            s[2] = ();
5475        }
5476
5477        #[test]
5478        fn test_new_box_slice_zeroed_zst_empty() {
5479            let s: Box<[()]> = <()>::new_box_slice_zeroed(0);
5480            assert_eq!(s.len(), 0);
5481        }
5482
5483        #[test]
5484        #[should_panic(expected = "mem::size_of::<Self>() * len overflows `usize`")]
5485        fn test_new_box_slice_zeroed_panics_mul_overflow() {
5486            let _ = u16::new_box_slice_zeroed(usize::MAX);
5487        }
5488
5489        #[test]
5490        #[should_panic(expected = "assertion failed: size <= max_alloc")]
5491        fn test_new_box_slice_zeroed_panics_isize_overflow() {
5492            let max = usize::try_from(isize::MAX).unwrap();
5493            let _ = u16::new_box_slice_zeroed((max / mem::size_of::<u16>()) + 1);
5494        }
5495    }
5496}
5497
5498#[cfg(feature = "alloc")]
5499#[doc(inline)]
5500pub use alloc_support::*;
5501
5502#[cfg(test)]
5503mod tests {
5504    #![allow(clippy::unreadable_literal)]
5505
5506    use core::{cell::UnsafeCell, convert::TryInto as _, ops::Deref};
5507
5508    use static_assertions::assert_impl_all;
5509
5510    use super::*;
5511    use crate::util::testutil::*;
5512
5513    // An unsized type.
5514    //
5515    // This is used to test the custom derives of our traits. The `[u8]` type
5516    // gets a hand-rolled impl, so it doesn't exercise our custom derives.
5517    #[derive(Debug, Eq, PartialEq, FromZeroes, FromBytes, AsBytes, Unaligned)]
5518    #[repr(transparent)]
5519    struct Unsized([u8]);
5520
5521    impl Unsized {
5522        fn from_mut_slice(slc: &mut [u8]) -> &mut Unsized {
5523            // SAFETY: This *probably* sound - since the layouts of `[u8]` and
5524            // `Unsized` are the same, so are the layouts of `&mut [u8]` and
5525            // `&mut Unsized`. [1] Even if it turns out that this isn't actually
5526            // guaranteed by the language spec, we can just change this since
5527            // it's in test code.
5528            //
5529            // [1] https://github.com/rust-lang/unsafe-code-guidelines/issues/375
5530            unsafe { mem::transmute(slc) }
5531        }
5532    }
5533
5534    /// Tests of when a sized `DstLayout` is extended with a sized field.
5535    #[allow(clippy::decimal_literal_representation)]
5536    #[test]
5537    fn test_dst_layout_extend_sized_with_sized() {
5538        // This macro constructs a layout corresponding to a `u8` and extends it
5539        // with a zero-sized trailing field of given alignment `n`. The macro
5540        // tests that the resulting layout has both size and alignment `min(n,
5541        // P)` for all valid values of `repr(packed(P))`.
5542        macro_rules! test_align_is_size {
5543            ($n:expr) => {
5544                let base = DstLayout::for_type::<u8>();
5545                let trailing_field = DstLayout::for_type::<elain::Align<$n>>();
5546
5547                let packs =
5548                    core::iter::once(None).chain((0..29).map(|p| NonZeroUsize::new(2usize.pow(p))));
5549
5550                for pack in packs {
5551                    let composite = base.extend(trailing_field, pack);
5552                    let max_align = pack.unwrap_or(DstLayout::CURRENT_MAX_ALIGN);
5553                    let align = $n.min(max_align.get());
5554                    assert_eq!(
5555                        composite,
5556                        DstLayout {
5557                            align: NonZeroUsize::new(align).unwrap(),
5558                            size_info: SizeInfo::Sized { _size: align }
5559                        }
5560                    )
5561                }
5562            };
5563        }
5564
5565        test_align_is_size!(1);
5566        test_align_is_size!(2);
5567        test_align_is_size!(4);
5568        test_align_is_size!(8);
5569        test_align_is_size!(16);
5570        test_align_is_size!(32);
5571        test_align_is_size!(64);
5572        test_align_is_size!(128);
5573        test_align_is_size!(256);
5574        test_align_is_size!(512);
5575        test_align_is_size!(1024);
5576        test_align_is_size!(2048);
5577        test_align_is_size!(4096);
5578        test_align_is_size!(8192);
5579        test_align_is_size!(16384);
5580        test_align_is_size!(32768);
5581        test_align_is_size!(65536);
5582        test_align_is_size!(131072);
5583        test_align_is_size!(262144);
5584        test_align_is_size!(524288);
5585        test_align_is_size!(1048576);
5586        test_align_is_size!(2097152);
5587        test_align_is_size!(4194304);
5588        test_align_is_size!(8388608);
5589        test_align_is_size!(16777216);
5590        test_align_is_size!(33554432);
5591        test_align_is_size!(67108864);
5592        test_align_is_size!(33554432);
5593        test_align_is_size!(134217728);
5594        test_align_is_size!(268435456);
5595    }
5596
5597    /// Tests of when a sized `DstLayout` is extended with a DST field.
5598    #[test]
5599    fn test_dst_layout_extend_sized_with_dst() {
5600        // Test that for all combinations of real-world alignments and
5601        // `repr_packed` values, that the extension of a sized `DstLayout`` with
5602        // a DST field correctly computes the trailing offset in the composite
5603        // layout.
5604
5605        let aligns = (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap());
5606        let packs = core::iter::once(None).chain(aligns.clone().map(Some));
5607
5608        for align in aligns {
5609            for pack in packs.clone() {
5610                let base = DstLayout::for_type::<u8>();
5611                let elem_size = 42;
5612                let trailing_field_offset = 11;
5613
5614                let trailing_field = DstLayout {
5615                    align,
5616                    size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5617                        _elem_size: elem_size,
5618                        _offset: 11,
5619                    }),
5620                };
5621
5622                let composite = base.extend(trailing_field, pack);
5623
5624                let max_align = pack.unwrap_or(DstLayout::CURRENT_MAX_ALIGN).get();
5625
5626                let align = align.get().min(max_align);
5627
5628                assert_eq!(
5629                    composite,
5630                    DstLayout {
5631                        align: NonZeroUsize::new(align).unwrap(),
5632                        size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5633                            _elem_size: elem_size,
5634                            _offset: align + trailing_field_offset,
5635                        }),
5636                    }
5637                )
5638            }
5639        }
5640    }
5641
5642    /// Tests that calling `pad_to_align` on a sized `DstLayout` adds the
5643    /// expected amount of trailing padding.
5644    #[test]
5645    fn test_dst_layout_pad_to_align_with_sized() {
5646        // For all valid alignments `align`, construct a one-byte layout aligned
5647        // to `align`, call `pad_to_align`, and assert that the size of the
5648        // resulting layout is equal to `align`.
5649        for align in (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap()) {
5650            let layout = DstLayout { align, size_info: SizeInfo::Sized { _size: 1 } };
5651
5652            assert_eq!(
5653                layout.pad_to_align(),
5654                DstLayout { align, size_info: SizeInfo::Sized { _size: align.get() } }
5655            );
5656        }
5657
5658        // Test explicitly-provided combinations of unpadded and padded
5659        // counterparts.
5660
5661        macro_rules! test {
5662            (unpadded { size: $unpadded_size:expr, align: $unpadded_align:expr }
5663                => padded { size: $padded_size:expr, align: $padded_align:expr }) => {
5664                let unpadded = DstLayout {
5665                    align: NonZeroUsize::new($unpadded_align).unwrap(),
5666                    size_info: SizeInfo::Sized { _size: $unpadded_size },
5667                };
5668                let padded = unpadded.pad_to_align();
5669
5670                assert_eq!(
5671                    padded,
5672                    DstLayout {
5673                        align: NonZeroUsize::new($padded_align).unwrap(),
5674                        size_info: SizeInfo::Sized { _size: $padded_size },
5675                    }
5676                );
5677            };
5678        }
5679
5680        test!(unpadded { size: 0, align: 4 } => padded { size: 0, align: 4 });
5681        test!(unpadded { size: 1, align: 4 } => padded { size: 4, align: 4 });
5682        test!(unpadded { size: 2, align: 4 } => padded { size: 4, align: 4 });
5683        test!(unpadded { size: 3, align: 4 } => padded { size: 4, align: 4 });
5684        test!(unpadded { size: 4, align: 4 } => padded { size: 4, align: 4 });
5685        test!(unpadded { size: 5, align: 4 } => padded { size: 8, align: 4 });
5686        test!(unpadded { size: 6, align: 4 } => padded { size: 8, align: 4 });
5687        test!(unpadded { size: 7, align: 4 } => padded { size: 8, align: 4 });
5688        test!(unpadded { size: 8, align: 4 } => padded { size: 8, align: 4 });
5689
5690        let current_max_align = DstLayout::CURRENT_MAX_ALIGN.get();
5691
5692        test!(unpadded { size: 1, align: current_max_align }
5693            => padded { size: current_max_align, align: current_max_align });
5694
5695        test!(unpadded { size: current_max_align + 1, align: current_max_align }
5696            => padded { size: current_max_align * 2, align: current_max_align });
5697    }
5698
5699    /// Tests that calling `pad_to_align` on a DST `DstLayout` is a no-op.
5700    #[test]
5701    fn test_dst_layout_pad_to_align_with_dst() {
5702        for align in (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap()) {
5703            for offset in 0..10 {
5704                for elem_size in 0..10 {
5705                    let layout = DstLayout {
5706                        align,
5707                        size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5708                            _offset: offset,
5709                            _elem_size: elem_size,
5710                        }),
5711                    };
5712                    assert_eq!(layout.pad_to_align(), layout);
5713                }
5714            }
5715        }
5716    }
5717
5718    // This test takes a long time when running under Miri, so we skip it in
5719    // that case. This is acceptable because this is a logic test that doesn't
5720    // attempt to expose UB.
5721    #[test]
5722    #[cfg_attr(miri, ignore)]
5723    fn testvalidate_cast_and_convert_metadata() {
5724        impl From<usize> for SizeInfo {
5725            fn from(_size: usize) -> SizeInfo {
5726                SizeInfo::Sized { _size }
5727            }
5728        }
5729
5730        impl From<(usize, usize)> for SizeInfo {
5731            fn from((_offset, _elem_size): (usize, usize)) -> SizeInfo {
5732                SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size })
5733            }
5734        }
5735
5736        fn layout<S: Into<SizeInfo>>(s: S, align: usize) -> DstLayout {
5737            DstLayout { size_info: s.into(), align: NonZeroUsize::new(align).unwrap() }
5738        }
5739
5740        /// This macro accepts arguments in the form of:
5741        ///
5742        ///           layout(_, _, _).validate(_, _, _), Ok(Some((_, _)))
5743        ///                  |  |  |           |  |  |            |  |
5744        ///    base_size ----+  |  |           |  |  |            |  |
5745        ///    align -----------+  |           |  |  |            |  |
5746        ///    trailing_size ------+           |  |  |            |  |
5747        ///    addr ---------------------------+  |  |            |  |
5748        ///    bytes_len -------------------------+  |            |  |
5749        ///    cast_type ----------------------------+            |  |
5750        ///    elems ---------------------------------------------+  |
5751        ///    split_at ---------------------------------------------+
5752        ///
5753        /// `.validate` is shorthand for `.validate_cast_and_convert_metadata`
5754        /// for brevity.
5755        ///
5756        /// Each argument can either be an iterator or a wildcard. Each
5757        /// wildcarded variable is implicitly replaced by an iterator over a
5758        /// representative sample of values for that variable. Each `test!`
5759        /// invocation iterates over every combination of values provided by
5760        /// each variable's iterator (ie, the cartesian product) and validates
5761        /// that the results are expected.
5762        ///
5763        /// The final argument uses the same syntax, but it has a different
5764        /// meaning:
5765        /// - If it is `Ok(pat)`, then the pattern `pat` is supplied to
5766        ///   `assert_matches!` to validate the computed result for each
5767        ///   combination of input values.
5768        /// - If it is `Err(msg)`, then `test!` validates that the call to
5769        ///   `validate_cast_and_convert_metadata` panics with the given panic
5770        ///   message.
5771        ///
5772        /// Note that the meta-variables that match these variables have the
5773        /// `tt` type, and some valid expressions are not valid `tt`s (such as
5774        /// `a..b`). In this case, wrap the expression in parentheses, and it
5775        /// will become valid `tt`.
5776        macro_rules! test {
5777            ($(:$sizes:expr =>)?
5778                layout($size:tt, $align:tt)
5779                .validate($addr:tt, $bytes_len:tt, $cast_type:tt), $expect:pat $(,)?
5780            ) => {
5781                itertools::iproduct!(
5782                    test!(@generate_size $size),
5783                    test!(@generate_align $align),
5784                    test!(@generate_usize $addr),
5785                    test!(@generate_usize $bytes_len),
5786                    test!(@generate_cast_type $cast_type)
5787                ).for_each(|(size_info, align, addr, bytes_len, cast_type)| {
5788                    // Temporarily disable the panic hook installed by the test
5789                    // harness. If we don't do this, all panic messages will be
5790                    // kept in an internal log. On its own, this isn't a
5791                    // problem, but if a non-caught panic ever happens (ie, in
5792                    // code later in this test not in this macro), all of the
5793                    // previously-buffered messages will be dumped, hiding the
5794                    // real culprit.
5795                    let previous_hook = std::panic::take_hook();
5796                    // I don't understand why, but this seems to be required in
5797                    // addition to the previous line.
5798                    std::panic::set_hook(Box::new(|_| {}));
5799                    let actual = std::panic::catch_unwind(|| {
5800                        layout(size_info, align).validate_cast_and_convert_metadata(addr, bytes_len, cast_type)
5801                    }).map_err(|d| {
5802                        *d.downcast::<&'static str>().expect("expected string panic message").as_ref()
5803                    });
5804                    std::panic::set_hook(previous_hook);
5805
5806                    assert_matches::assert_matches!(
5807                        actual, $expect,
5808                        "layout({size_info:?}, {align}).validate_cast_and_convert_metadata({addr}, {bytes_len}, {cast_type:?})",
5809                    );
5810                });
5811            };
5812            (@generate_usize _) => { 0..8 };
5813            // Generate sizes for both Sized and !Sized types.
5814            (@generate_size _) => {
5815                test!(@generate_size (_)).chain(test!(@generate_size (_, _)))
5816            };
5817            // Generate sizes for both Sized and !Sized types by chaining
5818            // specified iterators for each.
5819            (@generate_size ($sized_sizes:tt | $unsized_sizes:tt)) => {
5820                test!(@generate_size ($sized_sizes)).chain(test!(@generate_size $unsized_sizes))
5821            };
5822            // Generate sizes for Sized types.
5823            (@generate_size (_)) => { test!(@generate_size (0..8)) };
5824            (@generate_size ($sizes:expr)) => { $sizes.into_iter().map(Into::<SizeInfo>::into) };
5825            // Generate sizes for !Sized types.
5826            (@generate_size ($min_sizes:tt, $elem_sizes:tt)) => {
5827                itertools::iproduct!(
5828                    test!(@generate_min_size $min_sizes),
5829                    test!(@generate_elem_size $elem_sizes)
5830                ).map(Into::<SizeInfo>::into)
5831            };
5832            (@generate_fixed_size _) => { (0..8).into_iter().map(Into::<SizeInfo>::into) };
5833            (@generate_min_size _) => { 0..8 };
5834            (@generate_elem_size _) => { 1..8 };
5835            (@generate_align _) => { [1, 2, 4, 8, 16] };
5836            (@generate_opt_usize _) => { [None].into_iter().chain((0..8).map(Some).into_iter()) };
5837            (@generate_cast_type _) => { [_CastType::_Prefix, _CastType::_Suffix] };
5838            (@generate_cast_type $variant:ident) => { [_CastType::$variant] };
5839            // Some expressions need to be wrapped in parentheses in order to be
5840            // valid `tt`s (required by the top match pattern). See the comment
5841            // below for more details. This arm removes these parentheses to
5842            // avoid generating an `unused_parens` warning.
5843            (@$_:ident ($vals:expr)) => { $vals };
5844            (@$_:ident $vals:expr) => { $vals };
5845        }
5846
5847        const EVENS: [usize; 8] = [0, 2, 4, 6, 8, 10, 12, 14];
5848        const ODDS: [usize; 8] = [1, 3, 5, 7, 9, 11, 13, 15];
5849
5850        // base_size is too big for the memory region.
5851        test!(layout(((1..8) | ((1..8), (1..8))), _).validate(_, [0], _), Ok(None));
5852        test!(layout(((2..8) | ((2..8), (2..8))), _).validate(_, [1], _), Ok(None));
5853
5854        // addr is unaligned for prefix cast
5855        test!(layout(_, [2]).validate(ODDS, _, _Prefix), Ok(None));
5856        test!(layout(_, [2]).validate(ODDS, _, _Prefix), Ok(None));
5857
5858        // addr is aligned, but end of buffer is unaligned for suffix cast
5859        test!(layout(_, [2]).validate(EVENS, ODDS, _Suffix), Ok(None));
5860        test!(layout(_, [2]).validate(EVENS, ODDS, _Suffix), Ok(None));
5861
5862        // Unfortunately, these constants cannot easily be used in the
5863        // implementation of `validate_cast_and_convert_metadata`, since
5864        // `panic!` consumes a string literal, not an expression.
5865        //
5866        // It's important that these messages be in a separate module. If they
5867        // were at the function's top level, we'd pass them to `test!` as, e.g.,
5868        // `Err(TRAILING)`, which would run into a subtle Rust footgun - the
5869        // `TRAILING` identifier would be treated as a pattern to match rather
5870        // than a value to check for equality.
5871        mod msgs {
5872            pub(super) const TRAILING: &str =
5873                "attempted to cast to slice type with zero-sized element";
5874            pub(super) const OVERFLOW: &str = "`addr` + `bytes_len` > usize::MAX";
5875        }
5876
5877        // casts with ZST trailing element types are unsupported
5878        test!(layout((_, [0]), _).validate(_, _, _), Err(msgs::TRAILING),);
5879
5880        // addr + bytes_len must not overflow usize
5881        test!(layout(_, _).validate([usize::MAX], (1..100), _), Err(msgs::OVERFLOW));
5882        test!(layout(_, _).validate((1..100), [usize::MAX], _), Err(msgs::OVERFLOW));
5883        test!(
5884            layout(_, _).validate(
5885                [usize::MAX / 2 + 1, usize::MAX],
5886                [usize::MAX / 2 + 1, usize::MAX],
5887                _
5888            ),
5889            Err(msgs::OVERFLOW)
5890        );
5891
5892        // Validates that `validate_cast_and_convert_metadata` satisfies its own
5893        // documented safety postconditions, and also a few other properties
5894        // that aren't documented but we want to guarantee anyway.
5895        fn validate_behavior(
5896            (layout, addr, bytes_len, cast_type): (DstLayout, usize, usize, _CastType),
5897        ) {
5898            if let Some((elems, split_at)) =
5899                layout.validate_cast_and_convert_metadata(addr, bytes_len, cast_type)
5900            {
5901                let (size_info, align) = (layout.size_info, layout.align);
5902                let debug_str = format!(
5903                    "layout({size_info:?}, {align}).validate_cast_and_convert_metadata({addr}, {bytes_len}, {cast_type:?}) => ({elems}, {split_at})",
5904                );
5905
5906                // If this is a sized type (no trailing slice), then `elems` is
5907                // meaningless, but in practice we set it to 0. Callers are not
5908                // allowed to rely on this, but a lot of math is nicer if
5909                // they're able to, and some callers might accidentally do that.
5910                let sized = matches!(layout.size_info, SizeInfo::Sized { .. });
5911                assert!(!(sized && elems != 0), "{}", debug_str);
5912
5913                let resulting_size = match layout.size_info {
5914                    SizeInfo::Sized { _size } => _size,
5915                    SizeInfo::SliceDst(TrailingSliceLayout {
5916                        _offset: offset,
5917                        _elem_size: elem_size,
5918                    }) => {
5919                        let padded_size = |elems| {
5920                            let without_padding = offset + elems * elem_size;
5921                            without_padding
5922                                + util::core_layout::padding_needed_for(without_padding, align)
5923                        };
5924
5925                        let resulting_size = padded_size(elems);
5926                        // Test that `validate_cast_and_convert_metadata`
5927                        // computed the largest possible value that fits in the
5928                        // given range.
5929                        assert!(padded_size(elems + 1) > bytes_len, "{}", debug_str);
5930                        resulting_size
5931                    }
5932                };
5933
5934                // Test safety postconditions guaranteed by
5935                // `validate_cast_and_convert_metadata`.
5936                assert!(resulting_size <= bytes_len, "{}", debug_str);
5937                match cast_type {
5938                    _CastType::_Prefix => {
5939                        assert_eq!(addr % align, 0, "{}", debug_str);
5940                        assert_eq!(resulting_size, split_at, "{}", debug_str);
5941                    }
5942                    _CastType::_Suffix => {
5943                        assert_eq!(split_at, bytes_len - resulting_size, "{}", debug_str);
5944                        assert_eq!((addr + split_at) % align, 0, "{}", debug_str);
5945                    }
5946                }
5947            } else {
5948                let min_size = match layout.size_info {
5949                    SizeInfo::Sized { _size } => _size,
5950                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, .. }) => {
5951                        _offset + util::core_layout::padding_needed_for(_offset, layout.align)
5952                    }
5953                };
5954
5955                // If a cast is invalid, it is either because...
5956                // 1. there are insufficent bytes at the given region for type:
5957                let insufficient_bytes = bytes_len < min_size;
5958                // 2. performing the cast would misalign type:
5959                let base = match cast_type {
5960                    _CastType::_Prefix => 0,
5961                    _CastType::_Suffix => bytes_len,
5962                };
5963                let misaligned = (base + addr) % layout.align != 0;
5964
5965                assert!(insufficient_bytes || misaligned);
5966            }
5967        }
5968
5969        let sizes = 0..8;
5970        let elem_sizes = 1..8;
5971        let size_infos = sizes
5972            .clone()
5973            .map(Into::<SizeInfo>::into)
5974            .chain(itertools::iproduct!(sizes, elem_sizes).map(Into::<SizeInfo>::into));
5975        let layouts = itertools::iproduct!(size_infos, [1, 2, 4, 8, 16, 32])
5976            .filter(|(size_info, align)| !matches!(size_info, SizeInfo::Sized { _size } if _size % align != 0))
5977            .map(|(size_info, align)| layout(size_info, align));
5978        itertools::iproduct!(layouts, 0..8, 0..8, [_CastType::_Prefix, _CastType::_Suffix])
5979            .for_each(validate_behavior);
5980    }
5981
5982    #[test]
5983    #[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
5984    fn test_validate_rust_layout() {
5985        use core::ptr::NonNull;
5986
5987        // This test synthesizes pointers with various metadata and uses Rust's
5988        // built-in APIs to confirm that Rust makes decisions about type layout
5989        // which are consistent with what we believe is guaranteed by the
5990        // language. If this test fails, it doesn't just mean our code is wrong
5991        // - it means we're misunderstanding the language's guarantees.
5992
5993        #[derive(Debug)]
5994        struct MacroArgs {
5995            offset: usize,
5996            align: NonZeroUsize,
5997            elem_size: Option<usize>,
5998        }
5999
6000        /// # Safety
6001        ///
6002        /// `test` promises to only call `addr_of_slice_field` on a `NonNull<T>`
6003        /// which points to a valid `T`.
6004        ///
6005        /// `with_elems` must produce a pointer which points to a valid `T`.
6006        fn test<T: ?Sized, W: Fn(usize) -> NonNull<T>>(
6007            args: MacroArgs,
6008            with_elems: W,
6009            addr_of_slice_field: Option<fn(NonNull<T>) -> NonNull<u8>>,
6010        ) {
6011            let dst = args.elem_size.is_some();
6012            let layout = {
6013                let size_info = match args.elem_size {
6014                    Some(elem_size) => SizeInfo::SliceDst(TrailingSliceLayout {
6015                        _offset: args.offset,
6016                        _elem_size: elem_size,
6017                    }),
6018                    None => SizeInfo::Sized {
6019                        // Rust only supports types whose sizes are a multiple
6020                        // of their alignment. If the macro created a type like
6021                        // this:
6022                        //
6023                        //   #[repr(C, align(2))]
6024                        //   struct Foo([u8; 1]);
6025                        //
6026                        // ...then Rust will automatically round the type's size
6027                        // up to 2.
6028                        _size: args.offset
6029                            + util::core_layout::padding_needed_for(args.offset, args.align),
6030                    },
6031                };
6032                DstLayout { size_info, align: args.align }
6033            };
6034
6035            for elems in 0..128 {
6036                let ptr = with_elems(elems);
6037
6038                if let Some(addr_of_slice_field) = addr_of_slice_field {
6039                    let slc_field_ptr = addr_of_slice_field(ptr).as_ptr();
6040                    // SAFETY: Both `slc_field_ptr` and `ptr` are pointers to
6041                    // the same valid Rust object.
6042                    let offset: usize =
6043                        unsafe { slc_field_ptr.byte_offset_from(ptr.as_ptr()).try_into().unwrap() };
6044                    assert_eq!(offset, args.offset);
6045                }
6046
6047                // SAFETY: `ptr` points to a valid `T`.
6048                let (size, align) = unsafe {
6049                    (mem::size_of_val_raw(ptr.as_ptr()), mem::align_of_val_raw(ptr.as_ptr()))
6050                };
6051
6052                // Avoid expensive allocation when running under Miri.
6053                let assert_msg = if !cfg!(miri) {
6054                    format!("\n{args:?}\nsize:{size}, align:{align}")
6055                } else {
6056                    String::new()
6057                };
6058
6059                let without_padding =
6060                    args.offset + args.elem_size.map(|elem_size| elems * elem_size).unwrap_or(0);
6061                assert!(size >= without_padding, "{}", assert_msg);
6062                assert_eq!(align, args.align.get(), "{}", assert_msg);
6063
6064                // This encodes the most important part of the test: our
6065                // understanding of how Rust determines the layout of repr(C)
6066                // types. Sized repr(C) types are trivial, but DST types have
6067                // some subtlety. Note that:
6068                // - For sized types, `without_padding` is just the size of the
6069                //   type that we constructed for `Foo`. Since we may have
6070                //   requested a larger alignment, `Foo` may actually be larger
6071                //   than this, hence `padding_needed_for`.
6072                // - For unsized types, `without_padding` is dynamically
6073                //   computed from the offset, the element size, and element
6074                //   count. We expect that the size of the object should be
6075                //   `offset + elem_size * elems` rounded up to the next
6076                //   alignment.
6077                let expected_size = without_padding
6078                    + util::core_layout::padding_needed_for(without_padding, args.align);
6079                assert_eq!(expected_size, size, "{}", assert_msg);
6080
6081                // For zero-sized element types,
6082                // `validate_cast_and_convert_metadata` just panics, so we skip
6083                // testing those types.
6084                if args.elem_size.map(|elem_size| elem_size > 0).unwrap_or(true) {
6085                    let addr = ptr.addr().get();
6086                    let (got_elems, got_split_at) = layout
6087                        .validate_cast_and_convert_metadata(addr, size, _CastType::_Prefix)
6088                        .unwrap();
6089                    // Avoid expensive allocation when running under Miri.
6090                    let assert_msg = if !cfg!(miri) {
6091                        format!(
6092                            "{}\nvalidate_cast_and_convert_metadata({addr}, {size})",
6093                            assert_msg
6094                        )
6095                    } else {
6096                        String::new()
6097                    };
6098                    assert_eq!(got_split_at, size, "{}", assert_msg);
6099                    if dst {
6100                        assert!(got_elems >= elems, "{}", assert_msg);
6101                        if got_elems != elems {
6102                            // If `validate_cast_and_convert_metadata`
6103                            // returned more elements than `elems`, that
6104                            // means that `elems` is not the maximum number
6105                            // of elements that can fit in `size` - in other
6106                            // words, there is enough padding at the end of
6107                            // the value to fit at least one more element.
6108                            // If we use this metadata to synthesize a
6109                            // pointer, despite having a different element
6110                            // count, we still expect it to have the same
6111                            // size.
6112                            let got_ptr = with_elems(got_elems);
6113                            // SAFETY: `got_ptr` is a pointer to a valid `T`.
6114                            let size_of_got_ptr = unsafe { mem::size_of_val_raw(got_ptr.as_ptr()) };
6115                            assert_eq!(size_of_got_ptr, size, "{}", assert_msg);
6116                        }
6117                    } else {
6118                        // For sized casts, the returned element value is
6119                        // technically meaningless, and we don't guarantee any
6120                        // particular value. In practice, it's always zero.
6121                        assert_eq!(got_elems, 0, "{}", assert_msg)
6122                    }
6123                }
6124            }
6125        }
6126
6127        macro_rules! validate_against_rust {
6128            ($offset:literal, $align:literal $(, $elem_size:literal)?) => {{
6129                #[repr(C, align($align))]
6130                struct Foo([u8; $offset]$(, [[u8; $elem_size]])?);
6131
6132                let args = MacroArgs {
6133                    offset: $offset,
6134                    align: $align.try_into().unwrap(),
6135                    elem_size: {
6136                        #[allow(unused)]
6137                        let ret = None::<usize>;
6138                        $(let ret = Some($elem_size);)?
6139                        ret
6140                    }
6141                };
6142
6143                #[repr(C, align($align))]
6144                struct FooAlign;
6145                // Create an aligned buffer to use in order to synthesize
6146                // pointers to `Foo`. We don't ever load values from these
6147                // pointers - we just do arithmetic on them - so having a "real"
6148                // block of memory as opposed to a validly-aligned-but-dangling
6149                // pointer is only necessary to make Miri happy since we run it
6150                // with "strict provenance" checking enabled.
6151                let aligned_buf = Align::<_, FooAlign>::new([0u8; 1024]);
6152                let with_elems = |elems| {
6153                    let slc = NonNull::slice_from_raw_parts(NonNull::from(&aligned_buf.t), elems);
6154                    #[allow(clippy::as_conversions)]
6155                    NonNull::new(slc.as_ptr() as *mut Foo).unwrap()
6156                };
6157                let addr_of_slice_field = {
6158                    #[allow(unused)]
6159                    let f = None::<fn(NonNull<Foo>) -> NonNull<u8>>;
6160                    $(
6161                        // SAFETY: `test` promises to only call `f` with a `ptr`
6162                        // to a valid `Foo`.
6163                        let f: Option<fn(NonNull<Foo>) -> NonNull<u8>> = Some(|ptr: NonNull<Foo>| unsafe {
6164                            NonNull::new(ptr::addr_of_mut!((*ptr.as_ptr()).1)).unwrap().cast::<u8>()
6165                        });
6166                        let _ = $elem_size;
6167                    )?
6168                    f
6169                };
6170
6171                test::<Foo, _>(args, with_elems, addr_of_slice_field);
6172            }};
6173        }
6174
6175        // Every permutation of:
6176        // - offset in [0, 4]
6177        // - align in [1, 16]
6178        // - elem_size in [0, 4] (plus no elem_size)
6179        validate_against_rust!(0, 1);
6180        validate_against_rust!(0, 1, 0);
6181        validate_against_rust!(0, 1, 1);
6182        validate_against_rust!(0, 1, 2);
6183        validate_against_rust!(0, 1, 3);
6184        validate_against_rust!(0, 1, 4);
6185        validate_against_rust!(0, 2);
6186        validate_against_rust!(0, 2, 0);
6187        validate_against_rust!(0, 2, 1);
6188        validate_against_rust!(0, 2, 2);
6189        validate_against_rust!(0, 2, 3);
6190        validate_against_rust!(0, 2, 4);
6191        validate_against_rust!(0, 4);
6192        validate_against_rust!(0, 4, 0);
6193        validate_against_rust!(0, 4, 1);
6194        validate_against_rust!(0, 4, 2);
6195        validate_against_rust!(0, 4, 3);
6196        validate_against_rust!(0, 4, 4);
6197        validate_against_rust!(0, 8);
6198        validate_against_rust!(0, 8, 0);
6199        validate_against_rust!(0, 8, 1);
6200        validate_against_rust!(0, 8, 2);
6201        validate_against_rust!(0, 8, 3);
6202        validate_against_rust!(0, 8, 4);
6203        validate_against_rust!(0, 16);
6204        validate_against_rust!(0, 16, 0);
6205        validate_against_rust!(0, 16, 1);
6206        validate_against_rust!(0, 16, 2);
6207        validate_against_rust!(0, 16, 3);
6208        validate_against_rust!(0, 16, 4);
6209        validate_against_rust!(1, 1);
6210        validate_against_rust!(1, 1, 0);
6211        validate_against_rust!(1, 1, 1);
6212        validate_against_rust!(1, 1, 2);
6213        validate_against_rust!(1, 1, 3);
6214        validate_against_rust!(1, 1, 4);
6215        validate_against_rust!(1, 2);
6216        validate_against_rust!(1, 2, 0);
6217        validate_against_rust!(1, 2, 1);
6218        validate_against_rust!(1, 2, 2);
6219        validate_against_rust!(1, 2, 3);
6220        validate_against_rust!(1, 2, 4);
6221        validate_against_rust!(1, 4);
6222        validate_against_rust!(1, 4, 0);
6223        validate_against_rust!(1, 4, 1);
6224        validate_against_rust!(1, 4, 2);
6225        validate_against_rust!(1, 4, 3);
6226        validate_against_rust!(1, 4, 4);
6227        validate_against_rust!(1, 8);
6228        validate_against_rust!(1, 8, 0);
6229        validate_against_rust!(1, 8, 1);
6230        validate_against_rust!(1, 8, 2);
6231        validate_against_rust!(1, 8, 3);
6232        validate_against_rust!(1, 8, 4);
6233        validate_against_rust!(1, 16);
6234        validate_against_rust!(1, 16, 0);
6235        validate_against_rust!(1, 16, 1);
6236        validate_against_rust!(1, 16, 2);
6237        validate_against_rust!(1, 16, 3);
6238        validate_against_rust!(1, 16, 4);
6239        validate_against_rust!(2, 1);
6240        validate_against_rust!(2, 1, 0);
6241        validate_against_rust!(2, 1, 1);
6242        validate_against_rust!(2, 1, 2);
6243        validate_against_rust!(2, 1, 3);
6244        validate_against_rust!(2, 1, 4);
6245        validate_against_rust!(2, 2);
6246        validate_against_rust!(2, 2, 0);
6247        validate_against_rust!(2, 2, 1);
6248        validate_against_rust!(2, 2, 2);
6249        validate_against_rust!(2, 2, 3);
6250        validate_against_rust!(2, 2, 4);
6251        validate_against_rust!(2, 4);
6252        validate_against_rust!(2, 4, 0);
6253        validate_against_rust!(2, 4, 1);
6254        validate_against_rust!(2, 4, 2);
6255        validate_against_rust!(2, 4, 3);
6256        validate_against_rust!(2, 4, 4);
6257        validate_against_rust!(2, 8);
6258        validate_against_rust!(2, 8, 0);
6259        validate_against_rust!(2, 8, 1);
6260        validate_against_rust!(2, 8, 2);
6261        validate_against_rust!(2, 8, 3);
6262        validate_against_rust!(2, 8, 4);
6263        validate_against_rust!(2, 16);
6264        validate_against_rust!(2, 16, 0);
6265        validate_against_rust!(2, 16, 1);
6266        validate_against_rust!(2, 16, 2);
6267        validate_against_rust!(2, 16, 3);
6268        validate_against_rust!(2, 16, 4);
6269        validate_against_rust!(3, 1);
6270        validate_against_rust!(3, 1, 0);
6271        validate_against_rust!(3, 1, 1);
6272        validate_against_rust!(3, 1, 2);
6273        validate_against_rust!(3, 1, 3);
6274        validate_against_rust!(3, 1, 4);
6275        validate_against_rust!(3, 2);
6276        validate_against_rust!(3, 2, 0);
6277        validate_against_rust!(3, 2, 1);
6278        validate_against_rust!(3, 2, 2);
6279        validate_against_rust!(3, 2, 3);
6280        validate_against_rust!(3, 2, 4);
6281        validate_against_rust!(3, 4);
6282        validate_against_rust!(3, 4, 0);
6283        validate_against_rust!(3, 4, 1);
6284        validate_against_rust!(3, 4, 2);
6285        validate_against_rust!(3, 4, 3);
6286        validate_against_rust!(3, 4, 4);
6287        validate_against_rust!(3, 8);
6288        validate_against_rust!(3, 8, 0);
6289        validate_against_rust!(3, 8, 1);
6290        validate_against_rust!(3, 8, 2);
6291        validate_against_rust!(3, 8, 3);
6292        validate_against_rust!(3, 8, 4);
6293        validate_against_rust!(3, 16);
6294        validate_against_rust!(3, 16, 0);
6295        validate_against_rust!(3, 16, 1);
6296        validate_against_rust!(3, 16, 2);
6297        validate_against_rust!(3, 16, 3);
6298        validate_against_rust!(3, 16, 4);
6299        validate_against_rust!(4, 1);
6300        validate_against_rust!(4, 1, 0);
6301        validate_against_rust!(4, 1, 1);
6302        validate_against_rust!(4, 1, 2);
6303        validate_against_rust!(4, 1, 3);
6304        validate_against_rust!(4, 1, 4);
6305        validate_against_rust!(4, 2);
6306        validate_against_rust!(4, 2, 0);
6307        validate_against_rust!(4, 2, 1);
6308        validate_against_rust!(4, 2, 2);
6309        validate_against_rust!(4, 2, 3);
6310        validate_against_rust!(4, 2, 4);
6311        validate_against_rust!(4, 4);
6312        validate_against_rust!(4, 4, 0);
6313        validate_against_rust!(4, 4, 1);
6314        validate_against_rust!(4, 4, 2);
6315        validate_against_rust!(4, 4, 3);
6316        validate_against_rust!(4, 4, 4);
6317        validate_against_rust!(4, 8);
6318        validate_against_rust!(4, 8, 0);
6319        validate_against_rust!(4, 8, 1);
6320        validate_against_rust!(4, 8, 2);
6321        validate_against_rust!(4, 8, 3);
6322        validate_against_rust!(4, 8, 4);
6323        validate_against_rust!(4, 16);
6324        validate_against_rust!(4, 16, 0);
6325        validate_against_rust!(4, 16, 1);
6326        validate_against_rust!(4, 16, 2);
6327        validate_against_rust!(4, 16, 3);
6328        validate_against_rust!(4, 16, 4);
6329    }
6330
6331    #[test]
6332    fn test_known_layout() {
6333        // Test that `$ty` and `ManuallyDrop<$ty>` have the expected layout.
6334        // Test that `PhantomData<$ty>` has the same layout as `()` regardless
6335        // of `$ty`.
6336        macro_rules! test {
6337            ($ty:ty, $expect:expr) => {
6338                let expect = $expect;
6339                assert_eq!(<$ty as KnownLayout>::LAYOUT, expect);
6340                assert_eq!(<ManuallyDrop<$ty> as KnownLayout>::LAYOUT, expect);
6341                assert_eq!(<PhantomData<$ty> as KnownLayout>::LAYOUT, <() as KnownLayout>::LAYOUT);
6342            };
6343        }
6344
6345        let layout = |offset, align, _trailing_slice_elem_size| DstLayout {
6346            align: NonZeroUsize::new(align).unwrap(),
6347            size_info: match _trailing_slice_elem_size {
6348                None => SizeInfo::Sized { _size: offset },
6349                Some(elem_size) => SizeInfo::SliceDst(TrailingSliceLayout {
6350                    _offset: offset,
6351                    _elem_size: elem_size,
6352                }),
6353            },
6354        };
6355
6356        test!((), layout(0, 1, None));
6357        test!(u8, layout(1, 1, None));
6358        // Use `align_of` because `u64` alignment may be smaller than 8 on some
6359        // platforms.
6360        test!(u64, layout(8, mem::align_of::<u64>(), None));
6361        test!(AU64, layout(8, 8, None));
6362
6363        test!(Option<&'static ()>, usize::LAYOUT);
6364
6365        test!([()], layout(0, 1, Some(0)));
6366        test!([u8], layout(0, 1, Some(1)));
6367        test!(str, layout(0, 1, Some(1)));
6368    }
6369
6370    #[cfg(feature = "derive")]
6371    #[test]
6372    fn test_known_layout_derive() {
6373        // In this and other files (`late_compile_pass.rs`,
6374        // `mid_compile_pass.rs`, and `struct.rs`), we test success and failure
6375        // modes of `derive(KnownLayout)` for the following combination of
6376        // properties:
6377        //
6378        // +------------+--------------------------------------+-----------+
6379        // |            |      trailing field properties       |           |
6380        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6381        // |------------+----------+----------------+----------+-----------|
6382        // |          N |        N |              N |        N |      KL00 |
6383        // |          N |        N |              N |        Y |      KL01 |
6384        // |          N |        N |              Y |        N |      KL02 |
6385        // |          N |        N |              Y |        Y |      KL03 |
6386        // |          N |        Y |              N |        N |      KL04 |
6387        // |          N |        Y |              N |        Y |      KL05 |
6388        // |          N |        Y |              Y |        N |      KL06 |
6389        // |          N |        Y |              Y |        Y |      KL07 |
6390        // |          Y |        N |              N |        N |      KL08 |
6391        // |          Y |        N |              N |        Y |      KL09 |
6392        // |          Y |        N |              Y |        N |      KL10 |
6393        // |          Y |        N |              Y |        Y |      KL11 |
6394        // |          Y |        Y |              N |        N |      KL12 |
6395        // |          Y |        Y |              N |        Y |      KL13 |
6396        // |          Y |        Y |              Y |        N |      KL14 |
6397        // |          Y |        Y |              Y |        Y |      KL15 |
6398        // +------------+----------+----------------+----------+-----------+
6399
6400        struct NotKnownLayout<T = ()> {
6401            _t: T,
6402        }
6403
6404        #[derive(KnownLayout)]
6405        #[repr(C)]
6406        struct AlignSize<const ALIGN: usize, const SIZE: usize>
6407        where
6408            elain::Align<ALIGN>: elain::Alignment,
6409        {
6410            _align: elain::Align<ALIGN>,
6411            _size: [u8; SIZE],
6412        }
6413
6414        type AU16 = AlignSize<2, 2>;
6415        type AU32 = AlignSize<4, 4>;
6416
6417        fn _assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
6418
6419        let sized_layout = |align, size| DstLayout {
6420            align: NonZeroUsize::new(align).unwrap(),
6421            size_info: SizeInfo::Sized { _size: size },
6422        };
6423
6424        let unsized_layout = |align, elem_size, offset| DstLayout {
6425            align: NonZeroUsize::new(align).unwrap(),
6426            size_info: SizeInfo::SliceDst(TrailingSliceLayout {
6427                _offset: offset,
6428                _elem_size: elem_size,
6429            }),
6430        };
6431
6432        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6433        // |          N |        N |              N |        Y |      KL01 |
6434        #[derive(KnownLayout)]
6435        #[allow(dead_code)] // fields are never read
6436        struct KL01(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6437
6438        let expected = DstLayout::for_type::<KL01>();
6439
6440        assert_eq!(<KL01 as KnownLayout>::LAYOUT, expected);
6441        assert_eq!(<KL01 as KnownLayout>::LAYOUT, sized_layout(4, 8));
6442
6443        // ...with `align(N)`:
6444        #[derive(KnownLayout)]
6445        #[repr(align(64))]
6446        #[allow(dead_code)] // fields are never read
6447        struct KL01Align(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6448
6449        let expected = DstLayout::for_type::<KL01Align>();
6450
6451        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, expected);
6452        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6453
6454        // ...with `packed`:
6455        #[derive(KnownLayout)]
6456        #[repr(packed)]
6457        #[allow(dead_code)] // fields are never read
6458        struct KL01Packed(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6459
6460        let expected = DstLayout::for_type::<KL01Packed>();
6461
6462        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, expected);
6463        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, sized_layout(1, 6));
6464
6465        // ...with `packed(N)`:
6466        #[derive(KnownLayout)]
6467        #[repr(packed(2))]
6468        #[allow(dead_code)] // fields are never read
6469        struct KL01PackedN(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6470
6471        assert_impl_all!(KL01PackedN: KnownLayout);
6472
6473        let expected = DstLayout::for_type::<KL01PackedN>();
6474
6475        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, expected);
6476        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6477
6478        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6479        // |          N |        N |              Y |        Y |      KL03 |
6480        #[derive(KnownLayout)]
6481        #[allow(dead_code)] // fields are never read
6482        struct KL03(NotKnownLayout, u8);
6483
6484        let expected = DstLayout::for_type::<KL03>();
6485
6486        assert_eq!(<KL03 as KnownLayout>::LAYOUT, expected);
6487        assert_eq!(<KL03 as KnownLayout>::LAYOUT, sized_layout(1, 1));
6488
6489        // ... with `align(N)`
6490        #[derive(KnownLayout)]
6491        #[repr(align(64))]
6492        #[allow(dead_code)] // fields are never read
6493        struct KL03Align(NotKnownLayout<AU32>, u8);
6494
6495        let expected = DstLayout::for_type::<KL03Align>();
6496
6497        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, expected);
6498        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6499
6500        // ... with `packed`:
6501        #[derive(KnownLayout)]
6502        #[repr(packed)]
6503        #[allow(dead_code)] // fields are never read
6504        struct KL03Packed(NotKnownLayout<AU32>, u8);
6505
6506        let expected = DstLayout::for_type::<KL03Packed>();
6507
6508        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, expected);
6509        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, sized_layout(1, 5));
6510
6511        // ... with `packed(N)`
6512        #[derive(KnownLayout)]
6513        #[repr(packed(2))]
6514        #[allow(dead_code)] // fields are never read
6515        struct KL03PackedN(NotKnownLayout<AU32>, u8);
6516
6517        assert_impl_all!(KL03PackedN: KnownLayout);
6518
6519        let expected = DstLayout::for_type::<KL03PackedN>();
6520
6521        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, expected);
6522        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6523
6524        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6525        // |          N |        Y |              N |        Y |      KL05 |
6526        #[derive(KnownLayout)]
6527        #[allow(dead_code)] // fields are never read
6528        struct KL05<T>(u8, T);
6529
6530        fn _test_kl05<T>(t: T) -> impl KnownLayout {
6531            KL05(0u8, t)
6532        }
6533
6534        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6535        // |          N |        Y |              Y |        Y |      KL07 |
6536        #[derive(KnownLayout)]
6537        #[allow(dead_code)] // fields are never read
6538        struct KL07<T: KnownLayout>(u8, T);
6539
6540        fn _test_kl07<T: KnownLayout>(t: T) -> impl KnownLayout {
6541            let _ = KL07(0u8, t);
6542        }
6543
6544        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6545        // |          Y |        N |              Y |        N |      KL10 |
6546        #[derive(KnownLayout)]
6547        #[repr(C)]
6548        struct KL10(NotKnownLayout<AU32>, [u8]);
6549
6550        let expected = DstLayout::new_zst(None)
6551            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
6552            .extend(<[u8] as KnownLayout>::LAYOUT, None)
6553            .pad_to_align();
6554
6555        assert_eq!(<KL10 as KnownLayout>::LAYOUT, expected);
6556        assert_eq!(<KL10 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 4));
6557
6558        // ...with `align(N)`:
6559        #[derive(KnownLayout)]
6560        #[repr(C, align(64))]
6561        struct KL10Align(NotKnownLayout<AU32>, [u8]);
6562
6563        let repr_align = NonZeroUsize::new(64);
6564
6565        let expected = DstLayout::new_zst(repr_align)
6566            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
6567            .extend(<[u8] as KnownLayout>::LAYOUT, None)
6568            .pad_to_align();
6569
6570        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, expected);
6571        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, unsized_layout(64, 1, 4));
6572
6573        // ...with `packed`:
6574        #[derive(KnownLayout)]
6575        #[repr(C, packed)]
6576        struct KL10Packed(NotKnownLayout<AU32>, [u8]);
6577
6578        let repr_packed = NonZeroUsize::new(1);
6579
6580        let expected = DstLayout::new_zst(None)
6581            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
6582            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
6583            .pad_to_align();
6584
6585        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, expected);
6586        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, unsized_layout(1, 1, 4));
6587
6588        // ...with `packed(N)`:
6589        #[derive(KnownLayout)]
6590        #[repr(C, packed(2))]
6591        struct KL10PackedN(NotKnownLayout<AU32>, [u8]);
6592
6593        let repr_packed = NonZeroUsize::new(2);
6594
6595        let expected = DstLayout::new_zst(None)
6596            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
6597            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
6598            .pad_to_align();
6599
6600        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, expected);
6601        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4));
6602
6603        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6604        // |          Y |        N |              Y |        Y |      KL11 |
6605        #[derive(KnownLayout)]
6606        #[repr(C)]
6607        struct KL11(NotKnownLayout<AU64>, u8);
6608
6609        let expected = DstLayout::new_zst(None)
6610            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
6611            .extend(<u8 as KnownLayout>::LAYOUT, None)
6612            .pad_to_align();
6613
6614        assert_eq!(<KL11 as KnownLayout>::LAYOUT, expected);
6615        assert_eq!(<KL11 as KnownLayout>::LAYOUT, sized_layout(8, 16));
6616
6617        // ...with `align(N)`:
6618        #[derive(KnownLayout)]
6619        #[repr(C, align(64))]
6620        struct KL11Align(NotKnownLayout<AU64>, u8);
6621
6622        let repr_align = NonZeroUsize::new(64);
6623
6624        let expected = DstLayout::new_zst(repr_align)
6625            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
6626            .extend(<u8 as KnownLayout>::LAYOUT, None)
6627            .pad_to_align();
6628
6629        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, expected);
6630        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6631
6632        // ...with `packed`:
6633        #[derive(KnownLayout)]
6634        #[repr(C, packed)]
6635        struct KL11Packed(NotKnownLayout<AU64>, u8);
6636
6637        let repr_packed = NonZeroUsize::new(1);
6638
6639        let expected = DstLayout::new_zst(None)
6640            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
6641            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
6642            .pad_to_align();
6643
6644        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, expected);
6645        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, sized_layout(1, 9));
6646
6647        // ...with `packed(N)`:
6648        #[derive(KnownLayout)]
6649        #[repr(C, packed(2))]
6650        struct KL11PackedN(NotKnownLayout<AU64>, u8);
6651
6652        let repr_packed = NonZeroUsize::new(2);
6653
6654        let expected = DstLayout::new_zst(None)
6655            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
6656            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
6657            .pad_to_align();
6658
6659        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, expected);
6660        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, sized_layout(2, 10));
6661
6662        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6663        // |          Y |        Y |              Y |        N |      KL14 |
6664        #[derive(KnownLayout)]
6665        #[repr(C)]
6666        struct KL14<T: ?Sized + KnownLayout>(u8, T);
6667
6668        fn _test_kl14<T: ?Sized + KnownLayout>(kl: &KL14<T>) {
6669            _assert_kl(kl)
6670        }
6671
6672        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6673        // |          Y |        Y |              Y |        Y |      KL15 |
6674        #[derive(KnownLayout)]
6675        #[repr(C)]
6676        struct KL15<T: KnownLayout>(u8, T);
6677
6678        fn _test_kl15<T: KnownLayout>(t: T) -> impl KnownLayout {
6679            let _ = KL15(0u8, t);
6680        }
6681
6682        // Test a variety of combinations of field types:
6683        //  - ()
6684        //  - u8
6685        //  - AU16
6686        //  - [()]
6687        //  - [u8]
6688        //  - [AU16]
6689
6690        #[allow(clippy::upper_case_acronyms)]
6691        #[derive(KnownLayout)]
6692        #[repr(C)]
6693        struct KLTU<T, U: ?Sized>(T, U);
6694
6695        assert_eq!(<KLTU<(), ()> as KnownLayout>::LAYOUT, sized_layout(1, 0));
6696
6697        assert_eq!(<KLTU<(), u8> as KnownLayout>::LAYOUT, sized_layout(1, 1));
6698
6699        assert_eq!(<KLTU<(), AU16> as KnownLayout>::LAYOUT, sized_layout(2, 2));
6700
6701        assert_eq!(<KLTU<(), [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 0));
6702
6703        assert_eq!(<KLTU<(), [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0));
6704
6705        assert_eq!(<KLTU<(), [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 0));
6706
6707        assert_eq!(<KLTU<u8, ()> as KnownLayout>::LAYOUT, sized_layout(1, 1));
6708
6709        assert_eq!(<KLTU<u8, u8> as KnownLayout>::LAYOUT, sized_layout(1, 2));
6710
6711        assert_eq!(<KLTU<u8, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6712
6713        assert_eq!(<KLTU<u8, [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 1));
6714
6715        assert_eq!(<KLTU<u8, [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1));
6716
6717        assert_eq!(<KLTU<u8, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2));
6718
6719        assert_eq!(<KLTU<AU16, ()> as KnownLayout>::LAYOUT, sized_layout(2, 2));
6720
6721        assert_eq!(<KLTU<AU16, u8> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6722
6723        assert_eq!(<KLTU<AU16, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6724
6725        assert_eq!(<KLTU<AU16, [()]> as KnownLayout>::LAYOUT, unsized_layout(2, 0, 2));
6726
6727        assert_eq!(<KLTU<AU16, [u8]> as KnownLayout>::LAYOUT, unsized_layout(2, 1, 2));
6728
6729        assert_eq!(<KLTU<AU16, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2));
6730
6731        // Test a variety of field counts.
6732
6733        #[derive(KnownLayout)]
6734        #[repr(C)]
6735        struct KLF0;
6736
6737        assert_eq!(<KLF0 as KnownLayout>::LAYOUT, sized_layout(1, 0));
6738
6739        #[derive(KnownLayout)]
6740        #[repr(C)]
6741        struct KLF1([u8]);
6742
6743        assert_eq!(<KLF1 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0));
6744
6745        #[derive(KnownLayout)]
6746        #[repr(C)]
6747        struct KLF2(NotKnownLayout<u8>, [u8]);
6748
6749        assert_eq!(<KLF2 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1));
6750
6751        #[derive(KnownLayout)]
6752        #[repr(C)]
6753        struct KLF3(NotKnownLayout<u8>, NotKnownLayout<AU16>, [u8]);
6754
6755        assert_eq!(<KLF3 as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4));
6756
6757        #[derive(KnownLayout)]
6758        #[repr(C)]
6759        struct KLF4(NotKnownLayout<u8>, NotKnownLayout<AU16>, NotKnownLayout<AU32>, [u8]);
6760
6761        assert_eq!(<KLF4 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 8));
6762    }
6763
6764    #[test]
6765    fn test_object_safety() {
6766        fn _takes_from_zeroes(_: &dyn FromZeroes) {}
6767        fn _takes_from_bytes(_: &dyn FromBytes) {}
6768        fn _takes_unaligned(_: &dyn Unaligned) {}
6769    }
6770
6771    #[test]
6772    fn test_from_zeroes_only() {
6773        // Test types that implement `FromZeroes` but not `FromBytes`.
6774
6775        assert!(!bool::new_zeroed());
6776        assert_eq!(char::new_zeroed(), '\0');
6777
6778        #[cfg(feature = "alloc")]
6779        {
6780            assert_eq!(bool::new_box_zeroed(), Box::new(false));
6781            assert_eq!(char::new_box_zeroed(), Box::new('\0'));
6782
6783            assert_eq!(bool::new_box_slice_zeroed(3).as_ref(), [false, false, false]);
6784            assert_eq!(char::new_box_slice_zeroed(3).as_ref(), ['\0', '\0', '\0']);
6785
6786            assert_eq!(bool::new_vec_zeroed(3).as_ref(), [false, false, false]);
6787            assert_eq!(char::new_vec_zeroed(3).as_ref(), ['\0', '\0', '\0']);
6788        }
6789
6790        let mut string = "hello".to_string();
6791        let s: &mut str = string.as_mut();
6792        assert_eq!(s, "hello");
6793        s.zero();
6794        assert_eq!(s, "\0\0\0\0\0");
6795    }
6796
6797    #[test]
6798    fn test_read_write() {
6799        const VAL: u64 = 0x12345678;
6800        #[cfg(target_endian = "big")]
6801        const VAL_BYTES: [u8; 8] = VAL.to_be_bytes();
6802        #[cfg(target_endian = "little")]
6803        const VAL_BYTES: [u8; 8] = VAL.to_le_bytes();
6804
6805        // Test `FromBytes::{read_from, read_from_prefix, read_from_suffix}`.
6806
6807        assert_eq!(u64::read_from(&VAL_BYTES[..]), Some(VAL));
6808        // The first 8 bytes are from `VAL_BYTES` and the second 8 bytes are all
6809        // zeroes.
6810        let bytes_with_prefix: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
6811        assert_eq!(u64::read_from_prefix(&bytes_with_prefix[..]), Some(VAL));
6812        assert_eq!(u64::read_from_suffix(&bytes_with_prefix[..]), Some(0));
6813        // The first 8 bytes are all zeroes and the second 8 bytes are from
6814        // `VAL_BYTES`
6815        let bytes_with_suffix: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
6816        assert_eq!(u64::read_from_prefix(&bytes_with_suffix[..]), Some(0));
6817        assert_eq!(u64::read_from_suffix(&bytes_with_suffix[..]), Some(VAL));
6818
6819        // Test `AsBytes::{write_to, write_to_prefix, write_to_suffix}`.
6820
6821        let mut bytes = [0u8; 8];
6822        assert_eq!(VAL.write_to(&mut bytes[..]), Some(()));
6823        assert_eq!(bytes, VAL_BYTES);
6824        let mut bytes = [0u8; 16];
6825        assert_eq!(VAL.write_to_prefix(&mut bytes[..]), Some(()));
6826        let want: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
6827        assert_eq!(bytes, want);
6828        let mut bytes = [0u8; 16];
6829        assert_eq!(VAL.write_to_suffix(&mut bytes[..]), Some(()));
6830        let want: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
6831        assert_eq!(bytes, want);
6832    }
6833
6834    #[test]
6835    fn test_transmute() {
6836        // Test that memory is transmuted as expected.
6837        let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6838        let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6839        let x: [[u8; 2]; 4] = transmute!(array_of_u8s);
6840        assert_eq!(x, array_of_arrays);
6841        let x: [u8; 8] = transmute!(array_of_arrays);
6842        assert_eq!(x, array_of_u8s);
6843
6844        // Test that the source expression's value is forgotten rather than
6845        // dropped.
6846        #[derive(AsBytes)]
6847        #[repr(transparent)]
6848        struct PanicOnDrop(());
6849        impl Drop for PanicOnDrop {
6850            fn drop(&mut self) {
6851                panic!("PanicOnDrop::drop");
6852            }
6853        }
6854        #[allow(clippy::let_unit_value)]
6855        let _: () = transmute!(PanicOnDrop(()));
6856
6857        // Test that `transmute!` is legal in a const context.
6858        const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
6859        const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
6860        const X: [[u8; 2]; 4] = transmute!(ARRAY_OF_U8S);
6861        assert_eq!(X, ARRAY_OF_ARRAYS);
6862    }
6863
6864    #[test]
6865    fn test_transmute_ref() {
6866        // Test that memory is transmuted as expected.
6867        let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6868        let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6869        let x: &[[u8; 2]; 4] = transmute_ref!(&array_of_u8s);
6870        assert_eq!(*x, array_of_arrays);
6871        let x: &[u8; 8] = transmute_ref!(&array_of_arrays);
6872        assert_eq!(*x, array_of_u8s);
6873
6874        // Test that `transmute_ref!` is legal in a const context.
6875        const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
6876        const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
6877        #[allow(clippy::redundant_static_lifetimes)]
6878        const X: &'static [[u8; 2]; 4] = transmute_ref!(&ARRAY_OF_U8S);
6879        assert_eq!(*X, ARRAY_OF_ARRAYS);
6880
6881        // Test that it's legal to transmute a reference while shrinking the
6882        // lifetime (note that `X` has the lifetime `'static`).
6883        let x: &[u8; 8] = transmute_ref!(X);
6884        assert_eq!(*x, ARRAY_OF_U8S);
6885
6886        // Test that `transmute_ref!` supports decreasing alignment.
6887        let u = AU64(0);
6888        let array = [0, 0, 0, 0, 0, 0, 0, 0];
6889        let x: &[u8; 8] = transmute_ref!(&u);
6890        assert_eq!(*x, array);
6891
6892        // Test that a mutable reference can be turned into an immutable one.
6893        let mut x = 0u8;
6894        #[allow(clippy::useless_transmute)]
6895        let y: &u8 = transmute_ref!(&mut x);
6896        assert_eq!(*y, 0);
6897    }
6898
6899    #[test]
6900    fn test_transmute_mut() {
6901        // Test that memory is transmuted as expected.
6902        let mut array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6903        let mut array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6904        let x: &mut [[u8; 2]; 4] = transmute_mut!(&mut array_of_u8s);
6905        assert_eq!(*x, array_of_arrays);
6906        let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
6907        assert_eq!(*x, array_of_u8s);
6908
6909        {
6910            // Test that it's legal to transmute a reference while shrinking the
6911            // lifetime.
6912            let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
6913            assert_eq!(*x, array_of_u8s);
6914        }
6915        // Test that `transmute_mut!` supports decreasing alignment.
6916        let mut u = AU64(0);
6917        let array = [0, 0, 0, 0, 0, 0, 0, 0];
6918        let x: &[u8; 8] = transmute_mut!(&mut u);
6919        assert_eq!(*x, array);
6920
6921        // Test that a mutable reference can be turned into an immutable one.
6922        let mut x = 0u8;
6923        #[allow(clippy::useless_transmute)]
6924        let y: &u8 = transmute_mut!(&mut x);
6925        assert_eq!(*y, 0);
6926    }
6927
6928    #[test]
6929    fn test_macros_evaluate_args_once() {
6930        let mut ctr = 0;
6931        let _: usize = transmute!({
6932            ctr += 1;
6933            0usize
6934        });
6935        assert_eq!(ctr, 1);
6936
6937        let mut ctr = 0;
6938        let _: &usize = transmute_ref!({
6939            ctr += 1;
6940            &0usize
6941        });
6942        assert_eq!(ctr, 1);
6943    }
6944
6945    #[test]
6946    fn test_include_value() {
6947        const AS_U32: u32 = include_value!("../testdata/include_value/data");
6948        assert_eq!(AS_U32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));
6949        const AS_I32: i32 = include_value!("../testdata/include_value/data");
6950        assert_eq!(AS_I32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));
6951    }
6952
6953    #[test]
6954    fn test_address() {
6955        // Test that the `Deref` and `DerefMut` implementations return a
6956        // reference which points to the right region of memory.
6957
6958        let buf = [0];
6959        let r = Ref::<_, u8>::new(&buf[..]).unwrap();
6960        let buf_ptr = buf.as_ptr();
6961        let deref_ptr: *const u8 = r.deref();
6962        assert_eq!(buf_ptr, deref_ptr);
6963
6964        let buf = [0];
6965        let r = Ref::<_, [u8]>::new_slice(&buf[..]).unwrap();
6966        let buf_ptr = buf.as_ptr();
6967        let deref_ptr = r.deref().as_ptr();
6968        assert_eq!(buf_ptr, deref_ptr);
6969    }
6970
6971    // Verify that values written to a `Ref` are properly shared between the
6972    // typed and untyped representations, that reads via `deref` and `read`
6973    // behave the same, and that writes via `deref_mut` and `write` behave the
6974    // same.
6975    fn test_new_helper(mut r: Ref<&mut [u8], AU64>) {
6976        // assert that the value starts at 0
6977        assert_eq!(*r, AU64(0));
6978        assert_eq!(r.read(), AU64(0));
6979
6980        // Assert that values written to the typed value are reflected in the
6981        // byte slice.
6982        const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
6983        *r = VAL1;
6984        assert_eq!(r.bytes(), &VAL1.to_bytes());
6985        *r = AU64(0);
6986        r.write(VAL1);
6987        assert_eq!(r.bytes(), &VAL1.to_bytes());
6988
6989        // Assert that values written to the byte slice are reflected in the
6990        // typed value.
6991        const VAL2: AU64 = AU64(!VAL1.0); // different from `VAL1`
6992        r.bytes_mut().copy_from_slice(&VAL2.to_bytes()[..]);
6993        assert_eq!(*r, VAL2);
6994        assert_eq!(r.read(), VAL2);
6995    }
6996
6997    // Verify that values written to a `Ref` are properly shared between the
6998    // typed and untyped representations; pass a value with `typed_len` `AU64`s
6999    // backed by an array of `typed_len * 8` bytes.
7000    fn test_new_helper_slice(mut r: Ref<&mut [u8], [AU64]>, typed_len: usize) {
7001        // Assert that the value starts out zeroed.
7002        assert_eq!(&*r, vec![AU64(0); typed_len].as_slice());
7003
7004        // Check the backing storage is the exact same slice.
7005        let untyped_len = typed_len * 8;
7006        assert_eq!(r.bytes().len(), untyped_len);
7007        assert_eq!(r.bytes().as_ptr(), r.as_ptr().cast::<u8>());
7008
7009        // Assert that values written to the typed value are reflected in the
7010        // byte slice.
7011        const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
7012        for typed in &mut *r {
7013            *typed = VAL1;
7014        }
7015        assert_eq!(r.bytes(), VAL1.0.to_ne_bytes().repeat(typed_len).as_slice());
7016
7017        // Assert that values written to the byte slice are reflected in the
7018        // typed value.
7019        const VAL2: AU64 = AU64(!VAL1.0); // different from VAL1
7020        r.bytes_mut().copy_from_slice(&VAL2.0.to_ne_bytes().repeat(typed_len));
7021        assert!(r.iter().copied().all(|x| x == VAL2));
7022    }
7023
7024    // Verify that values written to a `Ref` are properly shared between the
7025    // typed and untyped representations, that reads via `deref` and `read`
7026    // behave the same, and that writes via `deref_mut` and `write` behave the
7027    // same.
7028    fn test_new_helper_unaligned(mut r: Ref<&mut [u8], [u8; 8]>) {
7029        // assert that the value starts at 0
7030        assert_eq!(*r, [0; 8]);
7031        assert_eq!(r.read(), [0; 8]);
7032
7033        // Assert that values written to the typed value are reflected in the
7034        // byte slice.
7035        const VAL1: [u8; 8] = [0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00];
7036        *r = VAL1;
7037        assert_eq!(r.bytes(), &VAL1);
7038        *r = [0; 8];
7039        r.write(VAL1);
7040        assert_eq!(r.bytes(), &VAL1);
7041
7042        // Assert that values written to the byte slice are reflected in the
7043        // typed value.
7044        const VAL2: [u8; 8] = [0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF]; // different from VAL1
7045        r.bytes_mut().copy_from_slice(&VAL2[..]);
7046        assert_eq!(*r, VAL2);
7047        assert_eq!(r.read(), VAL2);
7048    }
7049
7050    // Verify that values written to a `Ref` are properly shared between the
7051    // typed and untyped representations; pass a value with `len` `u8`s backed
7052    // by an array of `len` bytes.
7053    fn test_new_helper_slice_unaligned(mut r: Ref<&mut [u8], [u8]>, len: usize) {
7054        // Assert that the value starts out zeroed.
7055        assert_eq!(&*r, vec![0u8; len].as_slice());
7056
7057        // Check the backing storage is the exact same slice.
7058        assert_eq!(r.bytes().len(), len);
7059        assert_eq!(r.bytes().as_ptr(), r.as_ptr());
7060
7061        // Assert that values written to the typed value are reflected in the
7062        // byte slice.
7063        let mut expected_bytes = [0xFF, 0x00].iter().copied().cycle().take(len).collect::<Vec<_>>();
7064        r.copy_from_slice(&expected_bytes);
7065        assert_eq!(r.bytes(), expected_bytes.as_slice());
7066
7067        // Assert that values written to the byte slice are reflected in the
7068        // typed value.
7069        for byte in &mut expected_bytes {
7070            *byte = !*byte; // different from `expected_len`
7071        }
7072        r.bytes_mut().copy_from_slice(&expected_bytes);
7073        assert_eq!(&*r, expected_bytes.as_slice());
7074    }
7075
7076    #[test]
7077    fn test_new_aligned_sized() {
7078        // Test that a properly-aligned, properly-sized buffer works for new,
7079        // new_from_prefix, and new_from_suffix, and that new_from_prefix and
7080        // new_from_suffix return empty slices. Test that a properly-aligned
7081        // buffer whose length is a multiple of the element size works for
7082        // new_slice. Test that xxx_zeroed behaves the same, and zeroes the
7083        // memory.
7084
7085        // A buffer with an alignment of 8.
7086        let mut buf = Align::<[u8; 8], AU64>::default();
7087        // `buf.t` should be aligned to 8, so this should always succeed.
7088        test_new_helper(Ref::<_, AU64>::new(&mut buf.t[..]).unwrap());
7089        let ascending: [u8; 8] = (0..8).collect::<Vec<_>>().try_into().unwrap();
7090        buf.t = ascending;
7091        test_new_helper(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).unwrap());
7092        {
7093            // In a block so that `r` and `suffix` don't live too long.
7094            buf.set_default();
7095            let (r, suffix) = Ref::<_, AU64>::new_from_prefix(&mut buf.t[..]).unwrap();
7096            assert!(suffix.is_empty());
7097            test_new_helper(r);
7098        }
7099        {
7100            buf.t = ascending;
7101            let (r, suffix) = Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).unwrap();
7102            assert!(suffix.is_empty());
7103            test_new_helper(r);
7104        }
7105        {
7106            buf.set_default();
7107            let (prefix, r) = Ref::<_, AU64>::new_from_suffix(&mut buf.t[..]).unwrap();
7108            assert!(prefix.is_empty());
7109            test_new_helper(r);
7110        }
7111        {
7112            buf.t = ascending;
7113            let (prefix, r) = Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).unwrap();
7114            assert!(prefix.is_empty());
7115            test_new_helper(r);
7116        }
7117
7118        // A buffer with alignment 8 and length 24. We choose this length very
7119        // intentionally: if we instead used length 16, then the prefix and
7120        // suffix lengths would be identical. In the past, we used length 16,
7121        // which resulted in this test failing to discover the bug uncovered in
7122        // #506.
7123        let mut buf = Align::<[u8; 24], AU64>::default();
7124        // `buf.t` should be aligned to 8 and have a length which is a multiple
7125        // of `size_of::<AU64>()`, so this should always succeed.
7126        test_new_helper_slice(Ref::<_, [AU64]>::new_slice(&mut buf.t[..]).unwrap(), 3);
7127        let ascending: [u8; 24] = (0..24).collect::<Vec<_>>().try_into().unwrap();
7128        // 16 ascending bytes followed by 8 zeros.
7129        let mut ascending_prefix = ascending;
7130        ascending_prefix[16..].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
7131        // 8 zeros followed by 16 ascending bytes.
7132        let mut ascending_suffix = ascending;
7133        ascending_suffix[..8].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
7134        test_new_helper_slice(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[..]).unwrap(), 3);
7135
7136        {
7137            buf.t = ascending_suffix;
7138            let (r, suffix) = Ref::<_, [AU64]>::new_slice_from_prefix(&mut buf.t[..], 1).unwrap();
7139            assert_eq!(suffix, &ascending[8..]);
7140            test_new_helper_slice(r, 1);
7141        }
7142        {
7143            buf.t = ascending_suffix;
7144            let (r, suffix) =
7145                Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], 1).unwrap();
7146            assert_eq!(suffix, &ascending[8..]);
7147            test_new_helper_slice(r, 1);
7148        }
7149        {
7150            buf.t = ascending_prefix;
7151            let (prefix, r) = Ref::<_, [AU64]>::new_slice_from_suffix(&mut buf.t[..], 1).unwrap();
7152            assert_eq!(prefix, &ascending[..16]);
7153            test_new_helper_slice(r, 1);
7154        }
7155        {
7156            buf.t = ascending_prefix;
7157            let (prefix, r) =
7158                Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], 1).unwrap();
7159            assert_eq!(prefix, &ascending[..16]);
7160            test_new_helper_slice(r, 1);
7161        }
7162    }
7163
7164    #[test]
7165    fn test_new_unaligned_sized() {
7166        // Test that an unaligned, properly-sized buffer works for
7167        // `new_unaligned`, `new_unaligned_from_prefix`, and
7168        // `new_unaligned_from_suffix`, and that `new_unaligned_from_prefix`
7169        // `new_unaligned_from_suffix` return empty slices. Test that an
7170        // unaligned buffer whose length is a multiple of the element size works
7171        // for `new_slice`. Test that `xxx_zeroed` behaves the same, and zeroes
7172        // the memory.
7173
7174        let mut buf = [0u8; 8];
7175        test_new_helper_unaligned(Ref::<_, [u8; 8]>::new_unaligned(&mut buf[..]).unwrap());
7176        buf = [0xFFu8; 8];
7177        test_new_helper_unaligned(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf[..]).unwrap());
7178        {
7179            // In a block so that `r` and `suffix` don't live too long.
7180            buf = [0u8; 8];
7181            let (r, suffix) = Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&mut buf[..]).unwrap();
7182            assert!(suffix.is_empty());
7183            test_new_helper_unaligned(r);
7184        }
7185        {
7186            buf = [0xFFu8; 8];
7187            let (r, suffix) =
7188                Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf[..]).unwrap();
7189            assert!(suffix.is_empty());
7190            test_new_helper_unaligned(r);
7191        }
7192        {
7193            buf = [0u8; 8];
7194            let (prefix, r) = Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&mut buf[..]).unwrap();
7195            assert!(prefix.is_empty());
7196            test_new_helper_unaligned(r);
7197        }
7198        {
7199            buf = [0xFFu8; 8];
7200            let (prefix, r) =
7201                Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf[..]).unwrap();
7202            assert!(prefix.is_empty());
7203            test_new_helper_unaligned(r);
7204        }
7205
7206        let mut buf = [0u8; 16];
7207        // `buf.t` should be aligned to 8 and have a length which is a multiple
7208        // of `size_of::AU64>()`, so this should always succeed.
7209        test_new_helper_slice_unaligned(
7210            Ref::<_, [u8]>::new_slice_unaligned(&mut buf[..]).unwrap(),
7211            16,
7212        );
7213        buf = [0xFFu8; 16];
7214        test_new_helper_slice_unaligned(
7215            Ref::<_, [u8]>::new_slice_unaligned_zeroed(&mut buf[..]).unwrap(),
7216            16,
7217        );
7218
7219        {
7220            buf = [0u8; 16];
7221            let (r, suffix) =
7222                Ref::<_, [u8]>::new_slice_unaligned_from_prefix(&mut buf[..], 8).unwrap();
7223            assert_eq!(suffix, [0; 8]);
7224            test_new_helper_slice_unaligned(r, 8);
7225        }
7226        {
7227            buf = [0xFFu8; 16];
7228            let (r, suffix) =
7229                Ref::<_, [u8]>::new_slice_unaligned_from_prefix_zeroed(&mut buf[..], 8).unwrap();
7230            assert_eq!(suffix, [0xFF; 8]);
7231            test_new_helper_slice_unaligned(r, 8);
7232        }
7233        {
7234            buf = [0u8; 16];
7235            let (prefix, r) =
7236                Ref::<_, [u8]>::new_slice_unaligned_from_suffix(&mut buf[..], 8).unwrap();
7237            assert_eq!(prefix, [0; 8]);
7238            test_new_helper_slice_unaligned(r, 8);
7239        }
7240        {
7241            buf = [0xFFu8; 16];
7242            let (prefix, r) =
7243                Ref::<_, [u8]>::new_slice_unaligned_from_suffix_zeroed(&mut buf[..], 8).unwrap();
7244            assert_eq!(prefix, [0xFF; 8]);
7245            test_new_helper_slice_unaligned(r, 8);
7246        }
7247    }
7248
7249    #[test]
7250    fn test_new_oversized() {
7251        // Test that a properly-aligned, overly-sized buffer works for
7252        // `new_from_prefix` and `new_from_suffix`, and that they return the
7253        // remainder and prefix of the slice respectively. Test that
7254        // `xxx_zeroed` behaves the same, and zeroes the memory.
7255
7256        let mut buf = Align::<[u8; 16], AU64>::default();
7257        {
7258            // In a block so that `r` and `suffix` don't live too long. `buf.t`
7259            // should be aligned to 8, so this should always succeed.
7260            let (r, suffix) = Ref::<_, AU64>::new_from_prefix(&mut buf.t[..]).unwrap();
7261            assert_eq!(suffix.len(), 8);
7262            test_new_helper(r);
7263        }
7264        {
7265            buf.t = [0xFFu8; 16];
7266            // `buf.t` should be aligned to 8, so this should always succeed.
7267            let (r, suffix) = Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).unwrap();
7268            // Assert that the suffix wasn't zeroed.
7269            assert_eq!(suffix, &[0xFFu8; 8]);
7270            test_new_helper(r);
7271        }
7272        {
7273            buf.set_default();
7274            // `buf.t` should be aligned to 8, so this should always succeed.
7275            let (prefix, r) = Ref::<_, AU64>::new_from_suffix(&mut buf.t[..]).unwrap();
7276            assert_eq!(prefix.len(), 8);
7277            test_new_helper(r);
7278        }
7279        {
7280            buf.t = [0xFFu8; 16];
7281            // `buf.t` should be aligned to 8, so this should always succeed.
7282            let (prefix, r) = Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).unwrap();
7283            // Assert that the prefix wasn't zeroed.
7284            assert_eq!(prefix, &[0xFFu8; 8]);
7285            test_new_helper(r);
7286        }
7287    }
7288
7289    #[test]
7290    fn test_new_unaligned_oversized() {
7291        // Test than an unaligned, overly-sized buffer works for
7292        // `new_unaligned_from_prefix` and `new_unaligned_from_suffix`, and that
7293        // they return the remainder and prefix of the slice respectively. Test
7294        // that `xxx_zeroed` behaves the same, and zeroes the memory.
7295
7296        let mut buf = [0u8; 16];
7297        {
7298            // In a block so that `r` and `suffix` don't live too long.
7299            let (r, suffix) = Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&mut buf[..]).unwrap();
7300            assert_eq!(suffix.len(), 8);
7301            test_new_helper_unaligned(r);
7302        }
7303        {
7304            buf = [0xFFu8; 16];
7305            let (r, suffix) =
7306                Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf[..]).unwrap();
7307            // Assert that the suffix wasn't zeroed.
7308            assert_eq!(suffix, &[0xFF; 8]);
7309            test_new_helper_unaligned(r);
7310        }
7311        {
7312            buf = [0u8; 16];
7313            let (prefix, r) = Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&mut buf[..]).unwrap();
7314            assert_eq!(prefix.len(), 8);
7315            test_new_helper_unaligned(r);
7316        }
7317        {
7318            buf = [0xFFu8; 16];
7319            let (prefix, r) =
7320                Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf[..]).unwrap();
7321            // Assert that the prefix wasn't zeroed.
7322            assert_eq!(prefix, &[0xFF; 8]);
7323            test_new_helper_unaligned(r);
7324        }
7325    }
7326
7327    #[test]
7328    fn test_ref_from_mut_from() {
7329        // Test `FromBytes::{ref_from, mut_from}{,_prefix,_suffix}` success cases
7330        // Exhaustive coverage for these methods is covered by the `Ref` tests above,
7331        // which these helper methods defer to.
7332
7333        let mut buf =
7334            Align::<[u8; 16], AU64>::new([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
7335
7336        assert_eq!(
7337            AU64::ref_from(&buf.t[8..]).unwrap().0.to_ne_bytes(),
7338            [8, 9, 10, 11, 12, 13, 14, 15]
7339        );
7340        let suffix = AU64::mut_from(&mut buf.t[8..]).unwrap();
7341        suffix.0 = 0x0101010101010101;
7342        // The `[u8:9]` is a non-half size of the full buffer, which would catch
7343        // `from_prefix` having the same implementation as `from_suffix` (issues #506, #511).
7344        assert_eq!(<[u8; 9]>::ref_from_suffix(&buf.t[..]).unwrap(), &[7u8, 1, 1, 1, 1, 1, 1, 1, 1]);
7345        let suffix = AU64::mut_from_suffix(&mut buf.t[1..]).unwrap();
7346        suffix.0 = 0x0202020202020202;
7347        <[u8; 10]>::mut_from_suffix(&mut buf.t[..]).unwrap()[0] = 42;
7348        assert_eq!(<[u8; 9]>::ref_from_prefix(&buf.t[..]).unwrap(), &[0, 1, 2, 3, 4, 5, 42, 7, 2]);
7349        <[u8; 2]>::mut_from_prefix(&mut buf.t[..]).unwrap()[1] = 30;
7350        assert_eq!(buf.t, [0, 30, 2, 3, 4, 5, 42, 7, 2, 2, 2, 2, 2, 2, 2, 2]);
7351    }
7352
7353    #[test]
7354    fn test_ref_from_mut_from_error() {
7355        // Test `FromBytes::{ref_from, mut_from}{,_prefix,_suffix}` error cases.
7356
7357        // Fail because the buffer is too large.
7358        let mut buf = Align::<[u8; 16], AU64>::default();
7359        // `buf.t` should be aligned to 8, so only the length check should fail.
7360        assert!(AU64::ref_from(&buf.t[..]).is_none());
7361        assert!(AU64::mut_from(&mut buf.t[..]).is_none());
7362        assert!(<[u8; 8]>::ref_from(&buf.t[..]).is_none());
7363        assert!(<[u8; 8]>::mut_from(&mut buf.t[..]).is_none());
7364
7365        // Fail because the buffer is too small.
7366        let mut buf = Align::<[u8; 4], AU64>::default();
7367        assert!(AU64::ref_from(&buf.t[..]).is_none());
7368        assert!(AU64::mut_from(&mut buf.t[..]).is_none());
7369        assert!(<[u8; 8]>::ref_from(&buf.t[..]).is_none());
7370        assert!(<[u8; 8]>::mut_from(&mut buf.t[..]).is_none());
7371        assert!(AU64::ref_from_prefix(&buf.t[..]).is_none());
7372        assert!(AU64::mut_from_prefix(&mut buf.t[..]).is_none());
7373        assert!(AU64::ref_from_suffix(&buf.t[..]).is_none());
7374        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_none());
7375        assert!(<[u8; 8]>::ref_from_prefix(&buf.t[..]).is_none());
7376        assert!(<[u8; 8]>::mut_from_prefix(&mut buf.t[..]).is_none());
7377        assert!(<[u8; 8]>::ref_from_suffix(&buf.t[..]).is_none());
7378        assert!(<[u8; 8]>::mut_from_suffix(&mut buf.t[..]).is_none());
7379
7380        // Fail because the alignment is insufficient.
7381        let mut buf = Align::<[u8; 13], AU64>::default();
7382        assert!(AU64::ref_from(&buf.t[1..]).is_none());
7383        assert!(AU64::mut_from(&mut buf.t[1..]).is_none());
7384        assert!(AU64::ref_from(&buf.t[1..]).is_none());
7385        assert!(AU64::mut_from(&mut buf.t[1..]).is_none());
7386        assert!(AU64::ref_from_prefix(&buf.t[1..]).is_none());
7387        assert!(AU64::mut_from_prefix(&mut buf.t[1..]).is_none());
7388        assert!(AU64::ref_from_suffix(&buf.t[..]).is_none());
7389        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_none());
7390    }
7391
7392    #[test]
7393    #[allow(clippy::cognitive_complexity)]
7394    fn test_new_error() {
7395        // Fail because the buffer is too large.
7396
7397        // A buffer with an alignment of 8.
7398        let mut buf = Align::<[u8; 16], AU64>::default();
7399        // `buf.t` should be aligned to 8, so only the length check should fail.
7400        assert!(Ref::<_, AU64>::new(&buf.t[..]).is_none());
7401        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).is_none());
7402        assert!(Ref::<_, [u8; 8]>::new_unaligned(&buf.t[..]).is_none());
7403        assert!(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf.t[..]).is_none());
7404
7405        // Fail because the buffer is too small.
7406
7407        // A buffer with an alignment of 8.
7408        let mut buf = Align::<[u8; 4], AU64>::default();
7409        // `buf.t` should be aligned to 8, so only the length check should fail.
7410        assert!(Ref::<_, AU64>::new(&buf.t[..]).is_none());
7411        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).is_none());
7412        assert!(Ref::<_, [u8; 8]>::new_unaligned(&buf.t[..]).is_none());
7413        assert!(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf.t[..]).is_none());
7414        assert!(Ref::<_, AU64>::new_from_prefix(&buf.t[..]).is_none());
7415        assert!(Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).is_none());
7416        assert!(Ref::<_, AU64>::new_from_suffix(&buf.t[..]).is_none());
7417        assert!(Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).is_none());
7418        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&buf.t[..]).is_none());
7419        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf.t[..]).is_none());
7420        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&buf.t[..]).is_none());
7421        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf.t[..]).is_none());
7422
7423        // Fail because the length is not a multiple of the element size.
7424
7425        let mut buf = Align::<[u8; 12], AU64>::default();
7426        // `buf.t` has length 12, but element size is 8.
7427        assert!(Ref::<_, [AU64]>::new_slice(&buf.t[..]).is_none());
7428        assert!(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[..]).is_none());
7429        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned(&buf.t[..]).is_none());
7430        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_zeroed(&mut buf.t[..]).is_none());
7431
7432        // Fail because the buffer is too short.
7433        let mut buf = Align::<[u8; 12], AU64>::default();
7434        // `buf.t` has length 12, but the element size is 8 (and we're expecting
7435        // two of them).
7436        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[..], 2).is_none());
7437        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], 2).is_none());
7438        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[..], 2).is_none());
7439        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], 2).is_none());
7440        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix(&buf.t[..], 2).is_none());
7441        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix_zeroed(&mut buf.t[..], 2)
7442            .is_none());
7443        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix(&buf.t[..], 2).is_none());
7444        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix_zeroed(&mut buf.t[..], 2)
7445            .is_none());
7446
7447        // Fail because the alignment is insufficient.
7448
7449        // A buffer with an alignment of 8. An odd buffer size is chosen so that
7450        // the last byte of the buffer has odd alignment.
7451        let mut buf = Align::<[u8; 13], AU64>::default();
7452        // Slicing from 1, we get a buffer with size 12 (so the length check
7453        // should succeed) but an alignment of only 1, which is insufficient.
7454        assert!(Ref::<_, AU64>::new(&buf.t[1..]).is_none());
7455        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[1..]).is_none());
7456        assert!(Ref::<_, AU64>::new_from_prefix(&buf.t[1..]).is_none());
7457        assert!(Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[1..]).is_none());
7458        assert!(Ref::<_, [AU64]>::new_slice(&buf.t[1..]).is_none());
7459        assert!(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[1..]).is_none());
7460        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[1..], 1).is_none());
7461        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[1..], 1).is_none());
7462        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[1..], 1).is_none());
7463        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[1..], 1).is_none());
7464        // Slicing is unnecessary here because `new_from_suffix[_zeroed]` use
7465        // the suffix of the slice, which has odd alignment.
7466        assert!(Ref::<_, AU64>::new_from_suffix(&buf.t[..]).is_none());
7467        assert!(Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).is_none());
7468
7469        // Fail due to arithmetic overflow.
7470
7471        let mut buf = Align::<[u8; 16], AU64>::default();
7472        let unreasonable_len = usize::MAX / mem::size_of::<AU64>() + 1;
7473        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[..], unreasonable_len).is_none());
7474        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], unreasonable_len)
7475            .is_none());
7476        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[..], unreasonable_len).is_none());
7477        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], unreasonable_len)
7478            .is_none());
7479        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix(&buf.t[..], unreasonable_len)
7480            .is_none());
7481        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix_zeroed(
7482            &mut buf.t[..],
7483            unreasonable_len
7484        )
7485        .is_none());
7486        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix(&buf.t[..], unreasonable_len)
7487            .is_none());
7488        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix_zeroed(
7489            &mut buf.t[..],
7490            unreasonable_len
7491        )
7492        .is_none());
7493    }
7494
7495    // Tests for ensuring that, if a ZST is passed into a slice-like function,
7496    // we always panic. Since these tests need to be separate per-function, and
7497    // they tend to take up a lot of space, we generate them using a macro in a
7498    // submodule instead. The submodule ensures that we can just re-use the name
7499    // of the function under test for the name of the test itself.
7500    mod test_zst_panics {
7501        macro_rules! zst_test {
7502            ($name:ident($($tt:tt)*), $constructor_in_panic_msg:tt) => {
7503                #[test]
7504                #[should_panic = concat!("Ref::", $constructor_in_panic_msg, " called on a zero-sized type")]
7505                fn $name() {
7506                    let mut buffer = [0u8];
7507                    let r = $crate::Ref::<_, [()]>::$name(&mut buffer[..], $($tt)*);
7508                    unreachable!("should have panicked, got {:?}", r);
7509                }
7510            }
7511        }
7512        zst_test!(new_slice(), "new_slice");
7513        zst_test!(new_slice_zeroed(), "new_slice");
7514        zst_test!(new_slice_from_prefix(1), "new_slice");
7515        zst_test!(new_slice_from_prefix_zeroed(1), "new_slice");
7516        zst_test!(new_slice_from_suffix(1), "new_slice");
7517        zst_test!(new_slice_from_suffix_zeroed(1), "new_slice");
7518        zst_test!(new_slice_unaligned(), "new_slice_unaligned");
7519        zst_test!(new_slice_unaligned_zeroed(), "new_slice_unaligned");
7520        zst_test!(new_slice_unaligned_from_prefix(1), "new_slice_unaligned");
7521        zst_test!(new_slice_unaligned_from_prefix_zeroed(1), "new_slice_unaligned");
7522        zst_test!(new_slice_unaligned_from_suffix(1), "new_slice_unaligned");
7523        zst_test!(new_slice_unaligned_from_suffix_zeroed(1), "new_slice_unaligned");
7524    }
7525
7526    #[test]
7527    fn test_as_bytes_methods() {
7528        /// Run a series of tests by calling `AsBytes` methods on `t`.
7529        ///
7530        /// `bytes` is the expected byte sequence returned from `t.as_bytes()`
7531        /// before `t` has been modified. `post_mutation` is the expected
7532        /// sequence returned from `t.as_bytes()` after `t.as_bytes_mut()[0]`
7533        /// has had its bits flipped (by applying `^= 0xFF`).
7534        ///
7535        /// `N` is the size of `t` in bytes.
7536        fn test<T: FromBytes + AsBytes + Debug + Eq + ?Sized, const N: usize>(
7537            t: &mut T,
7538            bytes: &[u8],
7539            post_mutation: &T,
7540        ) {
7541            // Test that we can access the underlying bytes, and that we get the
7542            // right bytes and the right number of bytes.
7543            assert_eq!(t.as_bytes(), bytes);
7544
7545            // Test that changes to the underlying byte slices are reflected in
7546            // the original object.
7547            t.as_bytes_mut()[0] ^= 0xFF;
7548            assert_eq!(t, post_mutation);
7549            t.as_bytes_mut()[0] ^= 0xFF;
7550
7551            // `write_to` rejects slices that are too small or too large.
7552            assert_eq!(t.write_to(&mut vec![0; N - 1][..]), None);
7553            assert_eq!(t.write_to(&mut vec![0; N + 1][..]), None);
7554
7555            // `write_to` works as expected.
7556            let mut bytes = [0; N];
7557            assert_eq!(t.write_to(&mut bytes[..]), Some(()));
7558            assert_eq!(bytes, t.as_bytes());
7559
7560            // `write_to_prefix` rejects slices that are too small.
7561            assert_eq!(t.write_to_prefix(&mut vec![0; N - 1][..]), None);
7562
7563            // `write_to_prefix` works with exact-sized slices.
7564            let mut bytes = [0; N];
7565            assert_eq!(t.write_to_prefix(&mut bytes[..]), Some(()));
7566            assert_eq!(bytes, t.as_bytes());
7567
7568            // `write_to_prefix` works with too-large slices, and any bytes past
7569            // the prefix aren't modified.
7570            let mut too_many_bytes = vec![0; N + 1];
7571            too_many_bytes[N] = 123;
7572            assert_eq!(t.write_to_prefix(&mut too_many_bytes[..]), Some(()));
7573            assert_eq!(&too_many_bytes[..N], t.as_bytes());
7574            assert_eq!(too_many_bytes[N], 123);
7575
7576            // `write_to_suffix` rejects slices that are too small.
7577            assert_eq!(t.write_to_suffix(&mut vec![0; N - 1][..]), None);
7578
7579            // `write_to_suffix` works with exact-sized slices.
7580            let mut bytes = [0; N];
7581            assert_eq!(t.write_to_suffix(&mut bytes[..]), Some(()));
7582            assert_eq!(bytes, t.as_bytes());
7583
7584            // `write_to_suffix` works with too-large slices, and any bytes
7585            // before the suffix aren't modified.
7586            let mut too_many_bytes = vec![0; N + 1];
7587            too_many_bytes[0] = 123;
7588            assert_eq!(t.write_to_suffix(&mut too_many_bytes[..]), Some(()));
7589            assert_eq!(&too_many_bytes[1..], t.as_bytes());
7590            assert_eq!(too_many_bytes[0], 123);
7591        }
7592
7593        #[derive(Debug, Eq, PartialEq, FromZeroes, FromBytes, AsBytes)]
7594        #[repr(C)]
7595        struct Foo {
7596            a: u32,
7597            b: Wrapping<u32>,
7598            c: Option<NonZeroU32>,
7599        }
7600
7601        let expected_bytes: Vec<u8> = if cfg!(target_endian = "little") {
7602            vec![1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]
7603        } else {
7604            vec![0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0]
7605        };
7606        let post_mutation_expected_a =
7607            if cfg!(target_endian = "little") { 0x00_00_00_FE } else { 0xFF_00_00_01 };
7608        test::<_, 12>(
7609            &mut Foo { a: 1, b: Wrapping(2), c: None },
7610            expected_bytes.as_bytes(),
7611            &Foo { a: post_mutation_expected_a, b: Wrapping(2), c: None },
7612        );
7613        test::<_, 3>(
7614            Unsized::from_mut_slice(&mut [1, 2, 3]),
7615            &[1, 2, 3],
7616            Unsized::from_mut_slice(&mut [0xFE, 2, 3]),
7617        );
7618    }
7619
7620    #[test]
7621    fn test_array() {
7622        #[derive(FromZeroes, FromBytes, AsBytes)]
7623        #[repr(C)]
7624        struct Foo {
7625            a: [u16; 33],
7626        }
7627
7628        let foo = Foo { a: [0xFFFF; 33] };
7629        let expected = [0xFFu8; 66];
7630        assert_eq!(foo.as_bytes(), &expected[..]);
7631    }
7632
7633    #[test]
7634    fn test_display_debug() {
7635        let buf = Align::<[u8; 8], u64>::default();
7636        let r = Ref::<_, u64>::new(&buf.t[..]).unwrap();
7637        assert_eq!(format!("{}", r), "0");
7638        assert_eq!(format!("{:?}", r), "Ref(0)");
7639
7640        let buf = Align::<[u8; 8], u64>::default();
7641        let r = Ref::<_, [u64]>::new_slice(&buf.t[..]).unwrap();
7642        assert_eq!(format!("{:?}", r), "Ref([0])");
7643    }
7644
7645    #[test]
7646    fn test_eq() {
7647        let buf1 = 0_u64;
7648        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7649        let buf2 = 0_u64;
7650        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7651        assert_eq!(r1, r2);
7652    }
7653
7654    #[test]
7655    fn test_ne() {
7656        let buf1 = 0_u64;
7657        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7658        let buf2 = 1_u64;
7659        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7660        assert_ne!(r1, r2);
7661    }
7662
7663    #[test]
7664    fn test_ord() {
7665        let buf1 = 0_u64;
7666        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7667        let buf2 = 1_u64;
7668        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7669        assert!(r1 < r2);
7670    }
7671
7672    #[test]
7673    fn test_new_zeroed() {
7674        assert!(!bool::new_zeroed());
7675        assert_eq!(u64::new_zeroed(), 0);
7676        // This test exists in order to exercise unsafe code, especially when
7677        // running under Miri.
7678        #[allow(clippy::unit_cmp)]
7679        {
7680            assert_eq!(<()>::new_zeroed(), ());
7681        }
7682    }
7683
7684    #[test]
7685    fn test_transparent_packed_generic_struct() {
7686        #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
7687        #[repr(transparent)]
7688        #[allow(dead_code)] // for the unused fields
7689        struct Foo<T> {
7690            _t: T,
7691            _phantom: PhantomData<()>,
7692        }
7693
7694        assert_impl_all!(Foo<u32>: FromZeroes, FromBytes, AsBytes);
7695        assert_impl_all!(Foo<u8>: Unaligned);
7696
7697        #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
7698        #[repr(packed)]
7699        #[allow(dead_code)] // for the unused fields
7700        struct Bar<T, U> {
7701            _t: T,
7702            _u: U,
7703        }
7704
7705        assert_impl_all!(Bar<u8, AU64>: FromZeroes, FromBytes, AsBytes, Unaligned);
7706    }
7707
7708    #[test]
7709    fn test_impls() {
7710        use core::borrow::Borrow;
7711
7712        // A type that can supply test cases for testing
7713        // `TryFromBytes::is_bit_valid`. All types passed to `assert_impls!`
7714        // must implement this trait; that macro uses it to generate runtime
7715        // tests for `TryFromBytes` impls.
7716        //
7717        // All `T: FromBytes` types are provided with a blanket impl. Other
7718        // types must implement `TryFromBytesTestable` directly (ie using
7719        // `impl_try_from_bytes_testable!`).
7720        trait TryFromBytesTestable {
7721            fn with_passing_test_cases<F: Fn(&Self)>(f: F);
7722            fn with_failing_test_cases<F: Fn(&[u8])>(f: F);
7723        }
7724
7725        impl<T: FromBytes> TryFromBytesTestable for T {
7726            fn with_passing_test_cases<F: Fn(&Self)>(f: F) {
7727                // Test with a zeroed value.
7728                f(&Self::new_zeroed());
7729
7730                let ffs = {
7731                    let mut t = Self::new_zeroed();
7732                    let ptr: *mut T = &mut t;
7733                    // SAFETY: `T: FromBytes`
7734                    unsafe { ptr::write_bytes(ptr.cast::<u8>(), 0xFF, mem::size_of::<T>()) };
7735                    t
7736                };
7737
7738                // Test with a value initialized with 0xFF.
7739                f(&ffs);
7740            }
7741
7742            fn with_failing_test_cases<F: Fn(&[u8])>(_f: F) {}
7743        }
7744
7745        // Implements `TryFromBytesTestable`.
7746        macro_rules! impl_try_from_bytes_testable {
7747            // Base case for recursion (when the list of types has run out).
7748            (=> @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {};
7749            // Implements for type(s) with no type parameters.
7750            ($ty:ty $(,$tys:ty)* => @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {
7751                impl TryFromBytesTestable for $ty {
7752                    impl_try_from_bytes_testable!(
7753                        @methods     @success $($success_case),*
7754                                 $(, @failure $($failure_case),*)?
7755                    );
7756                }
7757                impl_try_from_bytes_testable!($($tys),* => @success $($success_case),* $(, @failure $($failure_case),*)?);
7758            };
7759            // Implements for multiple types with no type parameters.
7760            ($($($ty:ty),* => @success $($success_case:expr), * $(, @failure $($failure_case:expr),*)?;)*) => {
7761                $(
7762                    impl_try_from_bytes_testable!($($ty),* => @success $($success_case),* $(, @failure $($failure_case),*)*);
7763                )*
7764            };
7765            // Implements only the methods; caller must invoke this from inside
7766            // an impl block.
7767            (@methods @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {
7768                fn with_passing_test_cases<F: Fn(&Self)>(_f: F) {
7769                    $(
7770                        _f($success_case.borrow());
7771                    )*
7772                }
7773
7774                fn with_failing_test_cases<F: Fn(&[u8])>(_f: F) {
7775                    $($(
7776                        let case = $failure_case.as_bytes();
7777                        _f(case.as_bytes());
7778                    )*)?
7779                }
7780            };
7781        }
7782
7783        // Note that these impls are only for types which are not `FromBytes`.
7784        // `FromBytes` types are covered by a preceding blanket impl.
7785        impl_try_from_bytes_testable!(
7786            bool => @success true, false,
7787                    @failure 2u8, 3u8, 0xFFu8;
7788            char => @success '\u{0}', '\u{D7FF}', '\u{E000}', '\u{10FFFF}',
7789                    @failure 0xD800u32, 0xDFFFu32, 0x110000u32;
7790            str  => @success "", "hello", "โค๏ธ๐Ÿงก๐Ÿ’›๐Ÿ’š๐Ÿ’™๐Ÿ’œ",
7791                    @failure [0, 159, 146, 150];
7792            [u8] => @success [], [0, 1, 2];
7793            NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32,
7794            NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128,
7795            NonZeroUsize, NonZeroIsize
7796                 => @success Self::new(1).unwrap(),
7797                    // Doing this instead of `0` ensures that we always satisfy
7798                    // the size and alignment requirements of `Self` (whereas
7799                    // `0` may be any integer type with a different size or
7800                    // alignment than some `NonZeroXxx` types).
7801                    @failure Option::<Self>::None;
7802            [bool]
7803                => @success [true, false], [false, true],
7804                    @failure [2u8], [3u8], [0xFFu8], [0u8, 1u8, 2u8];
7805        );
7806
7807        // Asserts that `$ty` implements any `$trait` and doesn't implement any
7808        // `!$trait`. Note that all `$trait`s must come before any `!$trait`s.
7809        //
7810        // For `T: TryFromBytes`, uses `TryFromBytesTestable` to test success
7811        // and failure cases for `TryFromBytes::is_bit_valid`.
7812        macro_rules! assert_impls {
7813            ($ty:ty: TryFromBytes) => {
7814                <$ty as TryFromBytesTestable>::with_passing_test_cases(|val| {
7815                    let c = Ptr::from(val);
7816                    // SAFETY:
7817                    // - Since `val` is a normal reference, `c` is guranteed to
7818                    //   be aligned, to point to a single allocation, and to
7819                    //   have a size which doesn't overflow `isize`.
7820                    // - Since `val` is a valid `$ty`, `c`'s referent satisfies
7821                    //   the bit validity constraints of `is_bit_valid`, which
7822                    //   are a superset of the bit validity constraints of
7823                    //   `$ty`.
7824                    let res = unsafe { <$ty as TryFromBytes>::is_bit_valid(c) };
7825                    assert!(res, "{}::is_bit_valid({:?}): got false, expected true", stringify!($ty), val);
7826
7827                    // TODO(#5): In addition to testing `is_bit_valid`, test the
7828                    // methods built on top of it. This would both allow us to
7829                    // test their implementations and actually convert the bytes
7830                    // to `$ty`, giving Miri a chance to catch if this is
7831                    // unsound (ie, if our `is_bit_valid` impl is buggy).
7832                    //
7833                    // The following code was tried, but it doesn't work because
7834                    // a) some types are not `AsBytes` and, b) some types are
7835                    // not `Sized`.
7836                    //
7837                    //   let r = <$ty as TryFromBytes>::try_from_ref(val.as_bytes()).unwrap();
7838                    //   assert_eq!(r, &val);
7839                    //   let r = <$ty as TryFromBytes>::try_from_mut(val.as_bytes_mut()).unwrap();
7840                    //   assert_eq!(r, &mut val);
7841                    //   let v = <$ty as TryFromBytes>::try_read_from(val.as_bytes()).unwrap();
7842                    //   assert_eq!(v, val);
7843                });
7844                #[allow(clippy::as_conversions)]
7845                <$ty as TryFromBytesTestable>::with_failing_test_cases(|c| {
7846                    let res = <$ty as TryFromBytes>::try_from_ref(c);
7847                    assert!(res.is_none(), "{}::is_bit_valid({:?}): got true, expected false", stringify!($ty), c);
7848                });
7849
7850                #[allow(dead_code)]
7851                const _: () = { static_assertions::assert_impl_all!($ty: TryFromBytes); };
7852            };
7853            ($ty:ty: $trait:ident) => {
7854                #[allow(dead_code)]
7855                const _: () = { static_assertions::assert_impl_all!($ty: $trait); };
7856            };
7857            ($ty:ty: !$trait:ident) => {
7858                #[allow(dead_code)]
7859                const _: () = { static_assertions::assert_not_impl_any!($ty: $trait); };
7860            };
7861            ($ty:ty: $($trait:ident),* $(,)? $(!$negative_trait:ident),*) => {
7862                $(
7863                    assert_impls!($ty: $trait);
7864                )*
7865
7866                $(
7867                    assert_impls!($ty: !$negative_trait);
7868                )*
7869            };
7870        }
7871
7872        // NOTE: The negative impl assertions here are not necessarily
7873        // prescriptive. They merely serve as change detectors to make sure
7874        // we're aware of what trait impls are getting added with a given
7875        // change. Of course, some impls would be invalid (e.g., `bool:
7876        // FromBytes`), and so this change detection is very important.
7877
7878        assert_impls!((): KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7879        assert_impls!(u8: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7880        assert_impls!(i8: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7881        assert_impls!(u16: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7882        assert_impls!(i16: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7883        assert_impls!(u32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7884        assert_impls!(i32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7885        assert_impls!(u64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7886        assert_impls!(i64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7887        assert_impls!(u128: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7888        assert_impls!(i128: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7889        assert_impls!(usize: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7890        assert_impls!(isize: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7891        assert_impls!(f32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7892        assert_impls!(f64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7893
7894        assert_impls!(bool: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7895        assert_impls!(char: KnownLayout, TryFromBytes, FromZeroes, AsBytes, !FromBytes, !Unaligned);
7896        assert_impls!(str: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7897
7898        assert_impls!(NonZeroU8: KnownLayout, TryFromBytes, AsBytes, Unaligned, !FromZeroes, !FromBytes);
7899        assert_impls!(NonZeroI8: KnownLayout, TryFromBytes, AsBytes, Unaligned, !FromZeroes, !FromBytes);
7900        assert_impls!(NonZeroU16: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7901        assert_impls!(NonZeroI16: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7902        assert_impls!(NonZeroU32: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7903        assert_impls!(NonZeroI32: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7904        assert_impls!(NonZeroU64: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7905        assert_impls!(NonZeroI64: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7906        assert_impls!(NonZeroU128: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7907        assert_impls!(NonZeroI128: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7908        assert_impls!(NonZeroUsize: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7909        assert_impls!(NonZeroIsize: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7910
7911        assert_impls!(Option<NonZeroU8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7912        assert_impls!(Option<NonZeroI8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7913        assert_impls!(Option<NonZeroU16>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7914        assert_impls!(Option<NonZeroI16>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7915        assert_impls!(Option<NonZeroU32>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7916        assert_impls!(Option<NonZeroI32>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7917        assert_impls!(Option<NonZeroU64>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7918        assert_impls!(Option<NonZeroI64>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7919        assert_impls!(Option<NonZeroU128>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7920        assert_impls!(Option<NonZeroI128>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7921        assert_impls!(Option<NonZeroUsize>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7922        assert_impls!(Option<NonZeroIsize>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7923
7924        // Implements none of the ZC traits.
7925        struct NotZerocopy;
7926
7927        #[rustfmt::skip]
7928        type FnManyArgs = fn(
7929            NotZerocopy, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
7930        ) -> (NotZerocopy, NotZerocopy);
7931
7932        // Allowed, because we're not actually using this type for FFI.
7933        #[allow(improper_ctypes_definitions)]
7934        #[rustfmt::skip]
7935        type ECFnManyArgs = extern "C" fn(
7936            NotZerocopy, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
7937        ) -> (NotZerocopy, NotZerocopy);
7938
7939        #[cfg(feature = "alloc")]
7940        assert_impls!(Option<Box<UnsafeCell<NotZerocopy>>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7941        assert_impls!(Option<Box<[UnsafeCell<NotZerocopy>]>>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7942        assert_impls!(Option<&'static UnsafeCell<NotZerocopy>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7943        assert_impls!(Option<&'static [UnsafeCell<NotZerocopy>]>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7944        assert_impls!(Option<&'static mut UnsafeCell<NotZerocopy>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7945        assert_impls!(Option<&'static mut [UnsafeCell<NotZerocopy>]>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7946        assert_impls!(Option<NonNull<UnsafeCell<NotZerocopy>>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7947        assert_impls!(Option<NonNull<[UnsafeCell<NotZerocopy>]>>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7948        assert_impls!(Option<fn()>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7949        assert_impls!(Option<FnManyArgs>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7950        assert_impls!(Option<extern "C" fn()>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7951        assert_impls!(Option<ECFnManyArgs>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7952
7953        assert_impls!(PhantomData<NotZerocopy>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7954        assert_impls!(PhantomData<[u8]>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7955
7956        assert_impls!(ManuallyDrop<u8>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7957        assert_impls!(ManuallyDrop<[u8]>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7958        assert_impls!(ManuallyDrop<NotZerocopy>: !TryFromBytes, !KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7959        assert_impls!(ManuallyDrop<[NotZerocopy]>: !TryFromBytes, !KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7960
7961        assert_impls!(MaybeUninit<u8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, Unaligned, !AsBytes);
7962        assert_impls!(MaybeUninit<NotZerocopy>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7963
7964        assert_impls!(Wrapping<u8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7965        assert_impls!(Wrapping<NotZerocopy>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7966
7967        assert_impls!(Unalign<u8>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7968        assert_impls!(Unalign<NotZerocopy>: Unaligned, !KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes);
7969
7970        assert_impls!([u8]: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7971        assert_impls!([bool]: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7972        assert_impls!([NotZerocopy]: !KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7973        assert_impls!([u8; 0]: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7974        assert_impls!([NotZerocopy; 0]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7975        assert_impls!([u8; 1]: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7976        assert_impls!([NotZerocopy; 1]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7977
7978        assert_impls!(*const NotZerocopy: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7979        assert_impls!(*mut NotZerocopy: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7980        assert_impls!(*const [NotZerocopy]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7981        assert_impls!(*mut [NotZerocopy]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7982        assert_impls!(*const dyn Debug: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7983        assert_impls!(*mut dyn Debug: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7984
7985        #[cfg(feature = "simd")]
7986        {
7987            #[allow(unused_macros)]
7988            macro_rules! test_simd_arch_mod {
7989                ($arch:ident, $($typ:ident),*) => {
7990                    {
7991                        use core::arch::$arch::{$($typ),*};
7992                        use crate::*;
7993                        $( assert_impls!($typ: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned); )*
7994                    }
7995                };
7996            }
7997            #[cfg(target_arch = "x86")]
7998            test_simd_arch_mod!(x86, __m128, __m128d, __m128i, __m256, __m256d, __m256i);
7999
8000            #[cfg(all(feature = "simd-nightly", target_arch = "x86"))]
8001            test_simd_arch_mod!(x86, __m512bh, __m512, __m512d, __m512i);
8002
8003            #[cfg(target_arch = "x86_64")]
8004            test_simd_arch_mod!(x86_64, __m128, __m128d, __m128i, __m256, __m256d, __m256i);
8005
8006            #[cfg(all(feature = "simd-nightly", target_arch = "x86_64"))]
8007            test_simd_arch_mod!(x86_64, __m512bh, __m512, __m512d, __m512i);
8008
8009            #[cfg(target_arch = "wasm32")]
8010            test_simd_arch_mod!(wasm32, v128);
8011
8012            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc"))]
8013            test_simd_arch_mod!(
8014                powerpc,
8015                vector_bool_long,
8016                vector_double,
8017                vector_signed_long,
8018                vector_unsigned_long
8019            );
8020
8021            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc64"))]
8022            test_simd_arch_mod!(
8023                powerpc64,
8024                vector_bool_long,
8025                vector_double,
8026                vector_signed_long,
8027                vector_unsigned_long
8028            );
8029            #[cfg(target_arch = "aarch64")]
8030            #[rustfmt::skip]
8031            test_simd_arch_mod!(
8032                aarch64, float32x2_t, float32x4_t, float64x1_t, float64x2_t, int8x8_t, int8x8x2_t,
8033                int8x8x3_t, int8x8x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int16x4_t,
8034                int16x8_t, int32x2_t, int32x4_t, int64x1_t, int64x2_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t,
8035                poly8x8x4_t, poly8x16_t, poly8x16x2_t, poly8x16x3_t, poly8x16x4_t, poly16x4_t, poly16x8_t,
8036                poly64x1_t, poly64x2_t, uint8x8_t, uint8x8x2_t, uint8x8x3_t, uint8x8x4_t, uint8x16_t,
8037                uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint16x4_t, uint16x8_t, uint32x2_t, uint32x4_t,
8038                uint64x1_t, uint64x2_t
8039            );
8040            #[cfg(all(feature = "simd-nightly", target_arch = "arm"))]
8041            #[rustfmt::skip]
8042            test_simd_arch_mod!(arm, int8x4_t, uint8x4_t);
8043        }
8044    }
8045}
8046
8047#[cfg(kani)]
8048mod proofs {
8049    use super::*;
8050
8051    impl kani::Arbitrary for DstLayout {
8052        fn any() -> Self {
8053            let align: NonZeroUsize = kani::any();
8054            let size_info: SizeInfo = kani::any();
8055
8056            kani::assume(align.is_power_of_two());
8057            kani::assume(align < DstLayout::THEORETICAL_MAX_ALIGN);
8058
8059            // For testing purposes, we most care about instantiations of
8060            // `DstLayout` that can correspond to actual Rust types. We use
8061            // `Layout` to verify that our `DstLayout` satisfies the validity
8062            // conditions of Rust layouts.
8063            kani::assume(
8064                match size_info {
8065                    SizeInfo::Sized { _size } => Layout::from_size_align(_size, align.get()),
8066                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size }) => {
8067                        // `SliceDst`` cannot encode an exact size, but we know
8068                        // it is at least `_offset` bytes.
8069                        Layout::from_size_align(_offset, align.get())
8070                    }
8071                }
8072                .is_ok(),
8073            );
8074
8075            Self { align: align, size_info: size_info }
8076        }
8077    }
8078
8079    impl kani::Arbitrary for SizeInfo {
8080        fn any() -> Self {
8081            let is_sized: bool = kani::any();
8082
8083            match is_sized {
8084                true => {
8085                    let size: usize = kani::any();
8086
8087                    kani::assume(size <= isize::MAX as _);
8088
8089                    SizeInfo::Sized { _size: size }
8090                }
8091                false => SizeInfo::SliceDst(kani::any()),
8092            }
8093        }
8094    }
8095
8096    impl kani::Arbitrary for TrailingSliceLayout {
8097        fn any() -> Self {
8098            let elem_size: usize = kani::any();
8099            let offset: usize = kani::any();
8100
8101            kani::assume(elem_size < isize::MAX as _);
8102            kani::assume(offset < isize::MAX as _);
8103
8104            TrailingSliceLayout { _elem_size: elem_size, _offset: offset }
8105        }
8106    }
8107
8108    #[kani::proof]
8109    fn prove_dst_layout_extend() {
8110        use crate::util::{core_layout::padding_needed_for, max, min};
8111
8112        let base: DstLayout = kani::any();
8113        let field: DstLayout = kani::any();
8114        let packed: Option<NonZeroUsize> = kani::any();
8115
8116        if let Some(max_align) = packed {
8117            kani::assume(max_align.is_power_of_two());
8118            kani::assume(base.align <= max_align);
8119        }
8120
8121        // The base can only be extended if it's sized.
8122        kani::assume(matches!(base.size_info, SizeInfo::Sized { .. }));
8123        let base_size = if let SizeInfo::Sized { _size: size } = base.size_info {
8124            size
8125        } else {
8126            unreachable!();
8127        };
8128
8129        // Under the above conditions, `DstLayout::extend` will not panic.
8130        let composite = base.extend(field, packed);
8131
8132        // The field's alignment is clamped by `max_align` (i.e., the
8133        // `packed` attribute, if any) [1].
8134        //
8135        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
8136        //
8137        //   The alignments of each field, for the purpose of positioning
8138        //   fields, is the smaller of the specified alignment and the
8139        //   alignment of the field's type.
8140        let field_align = min(field.align, packed.unwrap_or(DstLayout::THEORETICAL_MAX_ALIGN));
8141
8142        // The struct's alignment is the maximum of its previous alignment and
8143        // `field_align`.
8144        assert_eq!(composite.align, max(base.align, field_align));
8145
8146        // Compute the minimum amount of inter-field padding needed to
8147        // satisfy the field's alignment, and offset of the trailing field.
8148        // [1]
8149        //
8150        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
8151        //
8152        //   Inter-field padding is guaranteed to be the minimum required in
8153        //   order to satisfy each field's (possibly altered) alignment.
8154        let padding = padding_needed_for(base_size, field_align);
8155        let offset = base_size + padding;
8156
8157        // For testing purposes, we'll also construct `alloc::Layout`
8158        // stand-ins for `DstLayout`, and show that `extend` behaves
8159        // comparably on both types.
8160        let base_analog = Layout::from_size_align(base_size, base.align.get()).unwrap();
8161
8162        match field.size_info {
8163            SizeInfo::Sized { _size: field_size } => {
8164                if let SizeInfo::Sized { _size: composite_size } = composite.size_info {
8165                    // If the trailing field is sized, the resulting layout
8166                    // will be sized. Its size will be the sum of the
8167                    // preceeding layout, the size of the new field, and the
8168                    // size of inter-field padding between the two.
8169                    assert_eq!(composite_size, offset + field_size);
8170
8171                    let field_analog =
8172                        Layout::from_size_align(field_size, field_align.get()).unwrap();
8173
8174                    if let Ok((actual_composite, actual_offset)) = base_analog.extend(field_analog)
8175                    {
8176                        assert_eq!(actual_offset, offset);
8177                        assert_eq!(actual_composite.size(), composite_size);
8178                        assert_eq!(actual_composite.align(), composite.align.get());
8179                    } else {
8180                        // An error here reflects that composite of `base`
8181                        // and `field` cannot correspond to a real Rust type
8182                        // fragment, because such a fragment would violate
8183                        // the basic invariants of a valid Rust layout. At
8184                        // the time of writing, `DstLayout` is a little more
8185                        // permissive than `Layout`, so we don't assert
8186                        // anything in this branch (e.g., unreachability).
8187                    }
8188                } else {
8189                    panic!("The composite of two sized layouts must be sized.")
8190                }
8191            }
8192            SizeInfo::SliceDst(TrailingSliceLayout {
8193                _offset: field_offset,
8194                _elem_size: field_elem_size,
8195            }) => {
8196                if let SizeInfo::SliceDst(TrailingSliceLayout {
8197                    _offset: composite_offset,
8198                    _elem_size: composite_elem_size,
8199                }) = composite.size_info
8200                {
8201                    // The offset of the trailing slice component is the sum
8202                    // of the offset of the trailing field and the trailing
8203                    // slice offset within that field.
8204                    assert_eq!(composite_offset, offset + field_offset);
8205                    // The elem size is unchanged.
8206                    assert_eq!(composite_elem_size, field_elem_size);
8207
8208                    let field_analog =
8209                        Layout::from_size_align(field_offset, field_align.get()).unwrap();
8210
8211                    if let Ok((actual_composite, actual_offset)) = base_analog.extend(field_analog)
8212                    {
8213                        assert_eq!(actual_offset, offset);
8214                        assert_eq!(actual_composite.size(), composite_offset);
8215                        assert_eq!(actual_composite.align(), composite.align.get());
8216                    } else {
8217                        // An error here reflects that composite of `base`
8218                        // and `field` cannot correspond to a real Rust type
8219                        // fragment, because such a fragment would violate
8220                        // the basic invariants of a valid Rust layout. At
8221                        // the time of writing, `DstLayout` is a little more
8222                        // permissive than `Layout`, so we don't assert
8223                        // anything in this branch (e.g., unreachability).
8224                    }
8225                } else {
8226                    panic!("The extension of a layout with a DST must result in a DST.")
8227                }
8228            }
8229        }
8230    }
8231
8232    #[kani::proof]
8233    #[kani::should_panic]
8234    fn prove_dst_layout_extend_dst_panics() {
8235        let base: DstLayout = kani::any();
8236        let field: DstLayout = kani::any();
8237        let packed: Option<NonZeroUsize> = kani::any();
8238
8239        if let Some(max_align) = packed {
8240            kani::assume(max_align.is_power_of_two());
8241            kani::assume(base.align <= max_align);
8242        }
8243
8244        kani::assume(matches!(base.size_info, SizeInfo::SliceDst(..)));
8245
8246        let _ = base.extend(field, packed);
8247    }
8248
8249    #[kani::proof]
8250    fn prove_dst_layout_pad_to_align() {
8251        use crate::util::core_layout::padding_needed_for;
8252
8253        let layout: DstLayout = kani::any();
8254
8255        let padded: DstLayout = layout.pad_to_align();
8256
8257        // Calling `pad_to_align` does not alter the `DstLayout`'s alignment.
8258        assert_eq!(padded.align, layout.align);
8259
8260        if let SizeInfo::Sized { _size: unpadded_size } = layout.size_info {
8261            if let SizeInfo::Sized { _size: padded_size } = padded.size_info {
8262                // If the layout is sized, it will remain sized after padding is
8263                // added. Its sum will be its unpadded size and the size of the
8264                // trailing padding needed to satisfy its alignment
8265                // requirements.
8266                let padding = padding_needed_for(unpadded_size, layout.align);
8267                assert_eq!(padded_size, unpadded_size + padding);
8268
8269                // Prove that calling `DstLayout::pad_to_align` behaves
8270                // identically to `Layout::pad_to_align`.
8271                let layout_analog =
8272                    Layout::from_size_align(unpadded_size, layout.align.get()).unwrap();
8273                let padded_analog = layout_analog.pad_to_align();
8274                assert_eq!(padded_analog.align(), layout.align.get());
8275                assert_eq!(padded_analog.size(), padded_size);
8276            } else {
8277                panic!("The padding of a sized layout must result in a sized layout.")
8278            }
8279        } else {
8280            // If the layout is a DST, padding cannot be statically added.
8281            assert_eq!(padded.size_info, layout.size_info);
8282        }
8283    }
8284}