Skip to main content

zerocopy/
lib.rs

1// SPDX-License-Identifier: BSD-2-Clause OR Apache-2.0 OR MIT
2//
3// Copyright 2018 The Fuchsia Authors
4//
5// Licensed under the 2-Clause BSD License <LICENSE-BSD or
6// https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0
7// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
8// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
9// This file may not be copied, modified, or distributed except according to
10// those terms.
11
12// After updating the following doc comment, make sure to run the following
13// command to update `README.md` based on its contents:
14//
15//   (cd .. && cargo -q run --manifest-path tools/Cargo.toml -p generate-readme) > README.md
16
17//! ***<span style="font-size: 140%">Fast, safe, <span
18//! style="color:red;">compile error</span>. Pick two.</span>***
19//!
20//! Zerocopy makes zero-cost memory manipulation effortless. We write `unsafe`
21//! so you don't have to.
22//!
23//! *For an overview of what's changed from zerocopy 0.7, check out our [release
24//! notes][release-notes], which include a step-by-step upgrading guide.*
25//!
26//! *Have questions? Need more out of zerocopy? Submit a [customer request
27//! issue][customer-request-issue] or ask the maintainers on
28//! [GitHub][github-q-a] or [Discord][discord]!*
29//!
30//! [customer-request-issue]: https://github.com/google/zerocopy/issues/new/choose
31//! [release-notes]: https://github.com/google/zerocopy/discussions/1680
32//! [github-q-a]: https://github.com/google/zerocopy/discussions/categories/q-a
33//! [discord]: https://discord.gg/MAvWH2R6zk
34//!
35//! # Overview
36//!
37//! ##### Conversion Traits
38//!
39//! Zerocopy provides four derivable traits for zero-cost conversions:
40//! - [`TryFromBytes`] indicates that a type may safely be converted from
41//!   certain byte sequences (conditional on runtime checks)
42//! - [`FromZeros`] indicates that a sequence of zero bytes represents a valid
43//!   instance of a type
44//! - [`FromBytes`] indicates that a type may safely be converted from an
45//!   arbitrary byte sequence
46//! - [`IntoBytes`] indicates that a type may safely be converted *to* a byte
47//!   sequence
48//!
49//! These traits support sized types, slices, and [slice DSTs][slice-dsts].
50//!
51//! [slice-dsts]: KnownLayout#dynamically-sized-types
52//!
53//! ##### Marker Traits
54//!
55//! Zerocopy provides three derivable marker traits that do not provide any
56//! functionality themselves, but are required to call certain methods provided
57//! by the conversion traits:
58//! - [`KnownLayout`] indicates that zerocopy can reason about certain layout
59//!   qualities of a type
60//! - [`Immutable`] indicates that a type is free from interior mutability,
61//!   except by ownership or an exclusive (`&mut`) borrow
62//! - [`Unaligned`] indicates that a type's alignment requirement is 1
63//!
64//! You should generally derive these marker traits whenever possible.
65//!
66//! ##### Conversion Macros
67//!
68//! Zerocopy provides six macros for safe casting between types:
69//!
70//! - ([`try_`][try_transmute])[`transmute`] (conditionally) converts a value of
71//!   one type to a value of another type of the same size
72//! - ([`try_`][try_transmute_mut])[`transmute_mut`] (conditionally) converts a
73//!   mutable reference of one type to a mutable reference of another type of
74//!   the same size
75//! - ([`try_`][try_transmute_ref])[`transmute_ref`] (conditionally) converts a
76//!   mutable or immutable reference of one type to an immutable reference of
77//!   another type of the same size
78//!
79//! These macros perform *compile-time* size and alignment checks, meaning that
80//! unconditional casts have zero cost at runtime. Conditional casts do not need
81//! to validate size or alignment runtime, but do need to validate contents.
82//!
83//! These macros cannot be used in generic contexts. For generic conversions,
84//! use the methods defined by the [conversion traits](#conversion-traits).
85//!
86//! ##### Byteorder-Aware Numerics
87//!
88//! Zerocopy provides byte-order aware integer types that support these
89//! conversions; see the [`byteorder`] module. These types are especially useful
90//! for network parsing.
91//!
92//! # Cargo Features
93//!
94//! - **`alloc`**
95//!   By default, `zerocopy` is `no_std`. When the `alloc` feature is enabled,
96//!   the `alloc` crate is added as a dependency, and some allocation-related
97//!   functionality is added.
98//!
99//! - **`std`**
100//!   By default, `zerocopy` is `no_std`. When the `std` feature is enabled, the
101//!   `std` crate is added as a dependency (ie, `no_std` is disabled), and
102//!   support for some `std` types is added. `std` implies `alloc`.
103//!
104//! - **`derive`**
105//!   Provides derives for the core marker traits via the `zerocopy-derive`
106//!   crate. These derives are re-exported from `zerocopy`, so it is not
107//!   necessary to depend on `zerocopy-derive` directly.
108//!
109//!   However, you may experience better compile times if you instead directly
110//!   depend on both `zerocopy` and `zerocopy-derive` in your `Cargo.toml`,
111//!   since doing so will allow Rust to compile these crates in parallel. To do
112//!   so, do *not* enable the `derive` feature, and list both dependencies in
113//!   your `Cargo.toml` with the same leading non-zero version number; e.g:
114//!
115//!   ```toml
116//!   [dependencies]
117//!   zerocopy = "0.X"
118//!   zerocopy-derive = "0.X"
119//!   ```
120//!
121//!   To avoid the risk of [duplicate import errors][duplicate-import-errors] if
122//!   one of your dependencies enables zerocopy's `derive` feature, import
123//!   derives as `use zerocopy_derive::*` rather than by name (e.g., `use
124//!   zerocopy_derive::FromBytes`).
125//!
126//! - **`simd`**
127//!   When the `simd` feature is enabled, `FromZeros`, `FromBytes`, and
128//!   `IntoBytes` impls are emitted for all stable SIMD types which exist on the
129//!   target platform. Note that the layout of SIMD types is not yet stabilized,
130//!   so these impls may be removed in the future if layout changes make them
131//!   invalid. For more information, see the Unsafe Code Guidelines Reference
132//!   page on the [layout of packed SIMD vectors][simd-layout].
133//!
134//! - **`simd-nightly`**
135//!   Enables the `simd` feature and adds support for SIMD types which are only
136//!   available on nightly. Since these types are unstable, support for any type
137//!   may be removed at any point in the future.
138//!
139//! - **`float-nightly`**
140//!   Adds support for the unstable `f16` and `f128` types. These types are
141//!   not yet fully implemented and may not be supported on all platforms.
142//!
143//! [duplicate-import-errors]: https://github.com/google/zerocopy/issues/1587
144//! [simd-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
145//!
146//! # Build Tuning
147//!
148//! ## `--cfg zerocopy_inline_always`
149//!
150//! Upgrades `#[inline]` to `#[inline(always)]` on many of zerocopy's public
151//! functions and methods. This provides a narrowly-scoped alternative that
152//! *may* improve the optimization of hot paths using zerocopy without the broad
153//! compile-time penalties of configuring `codegen-units=1`.
154//!
155//! # Security Ethos
156//!
157//! Zerocopy is expressly designed for use in security-critical contexts. We
158//! strive to ensure that that zerocopy code is sound under Rust's current
159//! memory model, and *any future memory model*. We ensure this by:
160//! - **...not 'guessing' about Rust's semantics.**
161//!   We annotate `unsafe` code with a precise rationale for its soundness that
162//!   cites a relevant section of Rust's official documentation. When Rust's
163//!   documented semantics are unclear, we work with the Rust Operational
164//!   Semantics Team to clarify Rust's documentation.
165//! - **...rigorously testing our implementation.**
166//!   We run tests using [Miri], ensuring that zerocopy is sound across a wide
167//!   array of supported target platforms of varying endianness and pointer
168//!   width, and across both current and experimental memory models of Rust.
169//! - **...formally proving the correctness of our implementation.**
170//!   We apply formal verification tools like [Kani][kani] to prove zerocopy's
171//!   correctness.
172//!
173//! For more information, see our full [soundness policy].
174//!
175//! [Miri]: https://github.com/rust-lang/miri
176//! [Kani]: https://github.com/model-checking/kani
177//! [soundness policy]: https://github.com/google/zerocopy/blob/main/zerocopy/POLICIES.md#soundness
178//!
179//! # Relationship to Project Safe Transmute
180//!
181//! [Project Safe Transmute] is an official initiative of the Rust Project to
182//! develop language-level support for safer transmutation. The Project consults
183//! with crates like zerocopy to identify aspects of safer transmutation that
184//! would benefit from compiler support, and has developed an [experimental,
185//! compiler-supported analysis][mcp-transmutability] which determines whether,
186//! for a given type, any value of that type may be soundly transmuted into
187//! another type. Once this functionality is sufficiently mature, zerocopy
188//! intends to replace its internal transmutability analysis (implemented by our
189//! custom derives) with the compiler-supported one. This change will likely be
190//! an implementation detail that is invisible to zerocopy's users.
191//!
192//! Project Safe Transmute will not replace the need for most of zerocopy's
193//! higher-level abstractions. The experimental compiler analysis is a tool for
194//! checking the soundness of `unsafe` code, not a tool to avoid writing
195//! `unsafe` code altogether. For the foreseeable future, crates like zerocopy
196//! will still be required in order to provide higher-level abstractions on top
197//! of the building block provided by Project Safe Transmute.
198//!
199//! [Project Safe Transmute]: https://rust-lang.github.io/rfcs/2835-project-safe-transmute.html
200//! [mcp-transmutability]: https://github.com/rust-lang/compiler-team/issues/411
201//!
202//! # MSRV
203//!
204//! See our [MSRV policy].
205//!
206//! [MSRV policy]: https://github.com/google/zerocopy/blob/main/zerocopy/POLICIES.md#msrv
207//!
208//! # Changelog
209//!
210//! Zerocopy uses [GitHub Releases].
211//!
212//! [GitHub Releases]: https://github.com/google/zerocopy/releases
213//!
214//! # Thanks
215//!
216//! Zerocopy is maintained by engineers at Google with help from [many wonderful
217//! contributors][contributors]. Thank you to everyone who has lent a hand in
218//! making Rust a little more secure!
219//!
220//! [contributors]: https://github.com/google/zerocopy/graphs/contributors
221
222// Sometimes we want to use lints which were added after our MSRV.
223// `unknown_lints` is `warn` by default and we deny warnings in CI, so without
224// this attribute, any unknown lint would cause a CI failure when testing with
225// our MSRV.
226#![allow(unknown_lints, non_local_definitions, unreachable_patterns)]
227#![deny(renamed_and_removed_lints)]
228#![deny(
229    anonymous_parameters,
230    deprecated_in_future,
231    late_bound_lifetime_arguments,
232    missing_copy_implementations,
233    missing_debug_implementations,
234    missing_docs,
235    path_statements,
236    patterns_in_fns_without_body,
237    rust_2018_idioms,
238    trivial_numeric_casts,
239    unreachable_pub,
240    unsafe_op_in_unsafe_fn,
241    unused_extern_crates,
242    // We intentionally choose not to deny `unused_qualifications`. When items
243    // are added to the prelude (e.g., `core::mem::size_of`), this has the
244    // consequence of making some uses trigger this lint on the latest toolchain
245    // (e.g., `mem::size_of`), but fixing it (e.g. by replacing with `size_of`)
246    // does not work on older toolchains.
247    //
248    // We tested a more complicated fix in #1413, but ultimately decided that,
249    // since this lint is just a minor style lint, the complexity isn't worth it
250    // - it's fine to occasionally have unused qualifications slip through,
251    // especially since these do not affect our user-facing API in any way.
252    variant_size_differences
253)]
254#![cfg_attr(
255    __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS,
256    deny(fuzzy_provenance_casts, lossy_provenance_casts)
257)]
258#![deny(
259    clippy::all,
260    clippy::alloc_instead_of_core,
261    clippy::arithmetic_side_effects,
262    clippy::as_underscore,
263    clippy::assertions_on_result_states,
264    clippy::as_conversions,
265    clippy::correctness,
266    clippy::dbg_macro,
267    clippy::decimal_literal_representation,
268    clippy::double_must_use,
269    clippy::get_unwrap,
270    clippy::indexing_slicing,
271    clippy::missing_inline_in_public_items,
272    clippy::missing_safety_doc,
273    clippy::multiple_unsafe_ops_per_block,
274    clippy::must_use_candidate,
275    clippy::must_use_unit,
276    clippy::obfuscated_if_else,
277    clippy::perf,
278    clippy::print_stdout,
279    clippy::return_self_not_must_use,
280    clippy::std_instead_of_core,
281    clippy::style,
282    clippy::suspicious,
283    clippy::todo,
284    clippy::undocumented_unsafe_blocks,
285    clippy::unimplemented,
286    clippy::unnested_or_patterns,
287    clippy::unwrap_used,
288    clippy::use_debug
289)]
290// `clippy::incompatible_msrv` (implied by `clippy::suspicious`): This sometimes
291// has false positives, and we test on our MSRV in CI, so it doesn't help us
292// anyway.
293#![allow(clippy::needless_lifetimes, clippy::type_complexity, clippy::incompatible_msrv)]
294#![deny(
295    rustdoc::bare_urls,
296    rustdoc::broken_intra_doc_links,
297    rustdoc::invalid_codeblock_attributes,
298    rustdoc::invalid_html_tags,
299    rustdoc::invalid_rust_codeblocks,
300    rustdoc::missing_crate_level_docs,
301    rustdoc::private_intra_doc_links
302)]
303// In test code, it makes sense to weight more heavily towards concise, readable
304// code over correct or debuggable code.
305#![cfg_attr(any(test, kani), allow(
306    // In tests, you get line numbers and have access to source code, so panic
307    // messages are less important. You also often unwrap a lot, which would
308    // make expect'ing instead very verbose.
309    clippy::unwrap_used,
310    // In tests, there's no harm to "panic risks" - the worst that can happen is
311    // that your test will fail, and you'll fix it. By contrast, panic risks in
312    // production code introduce the possibly of code panicking unexpectedly "in
313    // the field".
314    clippy::arithmetic_side_effects,
315    clippy::indexing_slicing,
316))]
317#![cfg_attr(not(any(test, kani, feature = "std")), no_std)]
318#![cfg_attr(
319    all(feature = "simd-nightly", target_arch = "arm"),
320    feature(stdarch_arm_neon_intrinsics)
321)]
322#![cfg_attr(
323    all(feature = "simd-nightly", any(target_arch = "powerpc", target_arch = "powerpc64")),
324    feature(stdarch_powerpc)
325)]
326#![cfg_attr(feature = "float-nightly", feature(f16, f128))]
327#![cfg_attr(doc_cfg, feature(doc_cfg))]
328#![cfg_attr(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, feature(coverage_attribute))]
329#![cfg_attr(
330    any(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, miri),
331    feature(layout_for_ptr)
332)]
333#![cfg_attr(all(test, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), feature(test))]
334
335// This is a hack to allow zerocopy-derive derives to work in this crate. They
336// assume that zerocopy is linked as an extern crate, so they access items from
337// it as `zerocopy::Xxx`. This makes that still work.
338#[cfg(any(feature = "derive", test))]
339extern crate self as zerocopy;
340
341#[cfg(all(test, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS))]
342extern crate test;
343
344#[doc(hidden)]
345#[macro_use]
346pub mod util;
347
348pub mod byte_slice;
349pub mod byteorder;
350mod deprecated;
351
352#[cfg(__ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE)]
353pub mod doctests;
354
355// This module is `pub` so that zerocopy's error types and error handling
356// documentation is grouped together in a cohesive module. In practice, we
357// expect most users to use the re-export of `error`'s items to avoid identifier
358// stuttering.
359pub mod error;
360mod impls;
361#[doc(hidden)]
362pub mod layout;
363mod macros;
364#[cfg_attr(not(zerocopy_unstable_ptr), doc(hidden))]
365#[cfg_attr(doc_cfg, doc(cfg(zerocopy_unstable_ptr)))]
366pub mod pointer;
367mod r#ref;
368mod split_at;
369// FIXME(#252): If we make this pub, come up with a better name.
370mod wrappers;
371
372use core::{
373    cell::{Cell, UnsafeCell},
374    cmp::Ordering,
375    fmt::{self, Debug, Display, Formatter},
376    hash::Hasher,
377    marker::PhantomData,
378    mem::{self, ManuallyDrop, MaybeUninit as CoreMaybeUninit},
379    num::{
380        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
381        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
382    },
383    ops::{Deref, DerefMut},
384    ptr::{self, NonNull},
385    slice,
386};
387#[cfg(feature = "std")]
388use std::io;
389
390#[doc(hidden)]
391pub use crate::pointer::{
392    invariant::{self, BecauseExclusive},
393    PtrInner,
394};
395pub use crate::{
396    byte_slice::*,
397    byteorder::*,
398    error::*,
399    r#ref::*,
400    split_at::{Split, SplitAt},
401    wrappers::*,
402};
403
404#[cfg(any(feature = "alloc", test))]
405extern crate alloc;
406#[cfg(any(feature = "alloc", test))]
407use alloc::{boxed::Box, vec::Vec};
408#[cfg(any(feature = "alloc", test))]
409use core::alloc::Layout;
410
411// Used by `KnownLayout`.
412#[doc(hidden)]
413pub use crate::layout::*;
414// Used by `TryFromBytes::is_safe`.
415#[doc(hidden)]
416pub use crate::pointer::{invariant::BecauseImmutable, Maybe, Ptr};
417// For each trait polyfill, as soon as the corresponding feature is stable, the
418// polyfill import will be unused because method/function resolution will prefer
419// the inherent method/function over a trait method/function. Thus, we suppress
420// the `unused_imports` warning.
421//
422// See the documentation on `util::polyfills` for more information.
423#[allow(unused_imports)]
424use crate::util::polyfills::{self, NonNullExt as _, NumExt as _};
425#[cfg_attr(not(zerocopy_unstable_ptr), doc(hidden))]
426#[cfg_attr(doc_cfg, doc(cfg(zerocopy_unstable_ptr)))]
427pub use crate::util::MetadataOf;
428
429#[cfg(all(test, not(__ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE)))]
430const _: () = {
431    #[deprecated = "Development of zerocopy using cargo is not supported. Please use `cargo.sh` or `win-cargo.bat` instead."]
432    #[allow(unused)]
433    const WARNING: () = ();
434    #[warn(deprecated)]
435    WARNING
436};
437
438#[cfg(all(any(feature = "derive", test), zerocopy_unstable_linux))]
439pub use zerocopy_derive::most_traits;
440/// Implements [`KnownLayout`].
441///
442/// This derive analyzes various aspects of a type's layout that are needed for
443/// some of zerocopy's APIs. It can be applied to structs, enums, and unions;
444/// e.g.:
445///
446/// ```
447/// # use zerocopy_derive::KnownLayout;
448/// #[derive(KnownLayout)]
449/// struct MyStruct {
450/// # /*
451///     ...
452/// # */
453/// }
454///
455/// #[derive(KnownLayout)]
456/// enum MyEnum {
457/// #   V00,
458/// # /*
459///     ...
460/// # */
461/// }
462///
463/// #[derive(KnownLayout)]
464/// union MyUnion {
465/// #   variant: u8,
466/// # /*
467///     ...
468/// # */
469/// }
470/// ```
471///
472/// # Limitations
473///
474/// This derive cannot currently be applied to unsized structs without an
475/// explicit `repr` attribute.
476///
477/// Some invocations of this derive run afoul of a [known bug] in Rust's type
478/// privacy checker. For example, this code:
479///
480/// ```compile_fail,E0446
481/// use zerocopy::*;
482/// # use zerocopy_derive::*;
483///
484/// #[derive(KnownLayout)]
485/// #[repr(C)]
486/// pub struct PublicType {
487///     leading: Foo,
488///     trailing: Bar,
489/// }
490///
491/// #[derive(KnownLayout)]
492/// struct Foo;
493///
494/// #[derive(KnownLayout)]
495/// struct Bar;
496/// ```
497///
498/// ...results in a compilation error:
499///
500/// ```text
501/// error[E0446]: private type `Bar` in public interface
502///  --> examples/bug.rs:3:10
503///    |
504/// 3  | #[derive(KnownLayout)]
505///    |          ^^^^^^^^^^^ can't leak private type
506/// ...
507/// 14 | struct Bar;
508///    | ---------- `Bar` declared as private
509///    |
510///    = note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
511/// ```
512///
513/// This issue arises when `#[derive(KnownLayout)]` is applied to `repr(C)`
514/// structs whose trailing field type is less public than the enclosing struct.
515///
516/// To work around this, mark the trailing field type `pub` and annotate it with
517/// `#[doc(hidden)]`; e.g.:
518///
519/// ```no_run
520/// use zerocopy::*;
521/// # use zerocopy_derive::*;
522///
523/// #[derive(KnownLayout)]
524/// #[repr(C)]
525/// pub struct PublicType {
526///     leading: Foo,
527///     trailing: Bar,
528/// }
529///
530/// #[derive(KnownLayout)]
531/// struct Foo;
532///
533/// #[doc(hidden)]
534/// #[derive(KnownLayout)]
535/// pub struct Bar; // <- `Bar` is now also `pub`
536/// ```
537///
538/// [known bug]: https://github.com/rust-lang/rust/issues/45713
539#[cfg(any(feature = "derive", test))]
540#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
541pub use zerocopy_derive::KnownLayout;
542// These exist so that code which was written against the old names will get
543// less confusing error messages when they upgrade to a more recent version of
544// zerocopy. On our MSRV toolchain, the error messages read, for example:
545//
546//   error[E0603]: trait `FromZeroes` is private
547//       --> examples/deprecated.rs:1:15
548//        |
549//   1    | use zerocopy::FromZeroes;
550//        |               ^^^^^^^^^^ private trait
551//        |
552//   note: the trait `FromZeroes` is defined here
553//       --> /Users/josh/workspace/zerocopy/src/lib.rs:1845:5
554//        |
555//   1845 | use FromZeros as FromZeroes;
556//        |     ^^^^^^^^^^^^^^^^^^^^^^^
557//
558// The "note" provides enough context to make it easy to figure out how to fix
559// the error.
560#[allow(unused)]
561use {FromZeros as FromZeroes, IntoBytes as AsBytes, Ref as LayoutVerified};
562
563/// Indicates that zerocopy can reason about certain aspects of a type's layout.
564///
565/// This trait is required by many of zerocopy's APIs. It supports sized types,
566/// slices, and [slice DSTs](#dynamically-sized-types).
567///
568/// # Implementation
569///
570/// **Do not implement this trait yourself!** Instead, use
571/// [`#[derive(KnownLayout)]`][derive]; e.g.:
572///
573/// ```
574/// # use zerocopy_derive::KnownLayout;
575/// #[derive(KnownLayout)]
576/// struct MyStruct {
577/// # /*
578///     ...
579/// # */
580/// }
581///
582/// #[derive(KnownLayout)]
583/// enum MyEnum {
584/// # /*
585///     ...
586/// # */
587/// }
588///
589/// #[derive(KnownLayout)]
590/// union MyUnion {
591/// #   variant: u8,
592/// # /*
593///     ...
594/// # */
595/// }
596/// ```
597///
598/// This derive performs a sophisticated analysis to deduce the layout
599/// characteristics of types. You **must** implement this trait via the derive.
600///
601/// # Dynamically-sized types
602///
603/// `KnownLayout` supports slice-based dynamically sized types ("slice DSTs").
604///
605/// A slice DST is a type whose trailing field is either a slice or another
606/// slice DST, rather than a type with fixed size. For example:
607///
608/// ```
609/// #[repr(C)]
610/// struct PacketHeader {
611/// # /*
612///     ...
613/// # */
614/// }
615///
616/// #[repr(C)]
617/// struct Packet {
618///     header: PacketHeader,
619///     body: [u8],
620/// }
621/// ```
622///
623/// It can be useful to think of slice DSTs as a generalization of slices - in
624/// other words, a normal slice is just the special case of a slice DST with
625/// zero leading fields. In particular:
626/// - Like slices, slice DSTs can have different lengths at runtime
627/// - Like slices, slice DSTs cannot be passed by-value, but only by reference
628///   or via other indirection such as `Box`
629/// - Like slices, a reference (or `Box`, or other pointer type) to a slice DST
630///   encodes the number of elements in the trailing slice field
631///
632/// ## Slice DST layout
633///
634/// Just like other composite Rust types, the layout of a slice DST is not
635/// well-defined unless it is specified using an explicit `#[repr(...)]`
636/// attribute such as `#[repr(C)]`. [Other representations are
637/// supported][reprs], but in this section, we'll use `#[repr(C)]` as our
638/// example.
639///
640/// A `#[repr(C)]` slice DST is laid out [just like sized `#[repr(C)]`
641/// types][repr-c-structs], but the presence of a variable-length field
642/// introduces the possibility of *dynamic padding*. In particular, it may be
643/// necessary to add trailing padding *after* the trailing slice field in order
644/// to satisfy the outer type's alignment, and the amount of padding required
645/// may be a function of the length of the trailing slice field. This is just a
646/// natural consequence of the normal `#[repr(C)]` rules applied to slice DSTs,
647/// but it can result in surprising behavior. For example, consider the
648/// following type:
649///
650/// ```
651/// #[repr(C)]
652/// struct Foo {
653///     a: u32,
654///     b: u8,
655///     z: [u16],
656/// }
657/// ```
658///
659/// Assuming that `u32` has alignment 4 (this is not true on all platforms),
660/// then `Foo` has alignment 4 as well. Here is the smallest possible value for
661/// `Foo`:
662///
663/// ```text
664/// byte offset | 01234567
665///       field | aaaab---
666///                    ><
667/// ```
668///
669/// In this value, `z` has length 0. Abiding by `#[repr(C)]`, the lowest offset
670/// that we can place `z` at is 5, but since `z` has alignment 2, we need to
671/// round up to offset 6. This means that there is one byte of padding between
672/// `b` and `z`, then 0 bytes of `z` itself (denoted `><` in this diagram), and
673/// then two bytes of padding after `z` in order to satisfy the overall
674/// alignment of `Foo`. The size of this instance is 8 bytes.
675///
676/// What about if `z` has length 1?
677///
678/// ```text
679/// byte offset | 01234567
680///       field | aaaab-zz
681/// ```
682///
683/// In this instance, `z` has length 1, and thus takes up 2 bytes. That means
684/// that we no longer need padding after `z` in order to satisfy `Foo`'s
685/// alignment. We've now seen two different values of `Foo` with two different
686/// lengths of `z`, but they both have the same size - 8 bytes.
687///
688/// What about if `z` has length 2?
689///
690/// ```text
691/// byte offset | 012345678901
692///       field | aaaab-zzzz--
693/// ```
694///
695/// Now `z` has length 2, and thus takes up 4 bytes. This brings our un-padded
696/// size to 10, and so we now need another 2 bytes of padding after `z` to
697/// satisfy `Foo`'s alignment.
698///
699/// Again, all of this is just a logical consequence of the `#[repr(C)]` rules
700/// applied to slice DSTs, but it can be surprising that the amount of trailing
701/// padding becomes a function of the trailing slice field's length, and thus
702/// can only be computed at runtime.
703///
704/// [reprs]: https://doc.rust-lang.org/reference/type-layout.html#representations
705/// [repr-c-structs]: https://doc.rust-lang.org/reference/type-layout.html#reprc-structs
706///
707/// ## What is a valid size?
708///
709/// There are two places in zerocopy's API that we refer to "a valid size" of a
710/// type. In normal casts or conversions, where the source is a byte slice, we
711/// need to know whether the source byte slice is a valid size of the
712/// destination type. In prefix or suffix casts, we need to know whether *there
713/// exists* a valid size of the destination type which fits in the source byte
714/// slice and, if so, what the largest such size is.
715///
716/// As outlined above, a slice DST's size is defined by the number of elements
717/// in its trailing slice field. However, there is not necessarily a 1-to-1
718/// mapping between trailing slice field length and overall size. As we saw in
719/// the previous section with the type `Foo`, instances with both 0 and 1
720/// elements in the trailing `z` field result in a `Foo` whose size is 8 bytes.
721///
722/// When we say "x is a valid size of `T`", we mean one of two things:
723/// - If `T: Sized`, then we mean that `x == size_of::<T>()`
724/// - If `T` is a slice DST, then we mean that there exists a `len` such that the instance of
725///   `T` with `len` trailing slice elements has size `x`
726///
727/// When we say "largest possible size of `T` that fits in a byte slice", we
728/// mean one of two things:
729/// - If `T: Sized`, then we mean `size_of::<T>()` if the byte slice is at least
730///   `size_of::<T>()` bytes long
731/// - If `T` is a slice DST, then we mean to consider all values, `len`, such
732///   that the instance of `T` with `len` trailing slice elements fits in the
733///   byte slice, and to choose the largest such `len`, if any
734///
735///
736/// # Safety
737///
738/// This trait does not convey any safety guarantees to code outside this crate.
739///
740/// You must not rely on the `#[doc(hidden)]` internals of `KnownLayout`. Future
741/// releases of zerocopy may make backwards-breaking changes to these items,
742/// including changes that only affect soundness, which may cause code which
743/// uses those items to silently become unsound.
744///
745#[cfg_attr(feature = "derive", doc = "[derive]: zerocopy_derive::KnownLayout")]
746#[cfg_attr(
747    not(feature = "derive"),
748    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.KnownLayout.html"),
749)]
750#[cfg_attr(
751    not(no_zerocopy_diagnostic_on_unimplemented_1_78_0),
752    diagnostic::on_unimplemented(note = "Consider adding `#[derive(KnownLayout)]` to `{Self}`")
753)]
754pub unsafe trait KnownLayout {
755    // The `Self: Sized` bound makes it so that `KnownLayout` can still be
756    // object safe. It's not currently object safe thanks to `const LAYOUT`, and
757    // it likely won't be in the future, but there's no reason not to be
758    // forwards-compatible with object safety.
759    #[doc(hidden)]
760    fn only_derive_is_allowed_to_implement_this_trait()
761    where
762        Self: Sized;
763
764    /// The type of metadata stored in a pointer to `Self`.
765    ///
766    /// This is `()` for sized types and [`usize`] for slice DSTs.
767    type PointerMetadata: PointerMetadata;
768
769    /// A maybe-uninitialized analog of `Self`
770    ///
771    /// # Safety
772    ///
773    /// `Self::LAYOUT` and `Self::MaybeUninit::LAYOUT` are identical.
774    /// `Self::MaybeUninit` admits uninitialized bytes in all positions.
775    #[doc(hidden)]
776    type MaybeUninit: ?Sized + KnownLayout<PointerMetadata = Self::PointerMetadata>;
777
778    /// The layout of `Self`.
779    ///
780    /// # Safety
781    ///
782    /// Callers may assume that `LAYOUT` accurately reflects the layout of
783    /// `Self`. In particular:
784    /// - `LAYOUT.align` is equal to `Self`'s alignment
785    /// - If `Self: Sized`, then `LAYOUT.size_info == SizeInfo::Sized { size }`
786    ///   where `size == size_of::<Self>()`
787    /// - If `Self` is a slice DST, then `LAYOUT.size_info ==
788    ///   SizeInfo::SliceDst(slice_layout)` where:
789    ///   - The size, `size`, of an instance of `Self` with `elems` trailing
790    ///     slice elements is equal to `slice_layout.offset +
791    ///     slice_layout.elem_size * elems` rounded up to the nearest multiple
792    ///     of `LAYOUT.align`
793    ///   - For such an instance, any bytes in the range `[slice_layout.offset +
794    ///     slice_layout.elem_size * elems, size)` are padding and must not be
795    ///     assumed to be initialized
796    #[doc(hidden)]
797    const LAYOUT: DstLayout;
798
799    /// SAFETY: The returned pointer has the same address and provenance as
800    /// `bytes`. If `Self` is a DST, the returned pointer's referent has `elems`
801    /// elements in its trailing slice.
802    #[doc(hidden)]
803    fn raw_from_ptr_len(bytes: NonNull<u8>, meta: Self::PointerMetadata) -> NonNull<Self>;
804
805    /// Extracts the metadata from a pointer to `Self`.
806    ///
807    /// # Safety
808    ///
809    /// `pointer_to_metadata` always returns the correct metadata stored in
810    /// `ptr`.
811    #[doc(hidden)]
812    fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata;
813
814    /// Computes the length of the byte range addressed by `ptr`.
815    ///
816    /// Returns `None` if the resulting length would not fit in an `usize`.
817    ///
818    /// # Safety
819    ///
820    /// Callers may assume that `size_of_val_raw` always returns the correct
821    /// size.
822    ///
823    /// Callers may assume that, if `ptr` addresses a byte range whose length
824    /// fits in an `usize`, this will return `Some`.
825    #[doc(hidden)]
826    #[must_use]
827    #[inline(always)]
828    fn size_of_val_raw(ptr: NonNull<Self>) -> Option<usize> {
829        let meta = Self::pointer_to_metadata(ptr.as_ptr());
830        // SAFETY: `size_for_metadata` promises to only return `None` if the
831        // resulting size would not fit in a `usize`.
832        Self::size_for_metadata(meta)
833    }
834
835    #[doc(hidden)]
836    #[must_use]
837    #[inline(always)]
838    fn raw_dangling() -> NonNull<Self> {
839        let meta = Self::PointerMetadata::from_elem_count(0);
840        Self::raw_from_ptr_len(NonNull::dangling(), meta)
841    }
842
843    /// Computes the size of an object of type `Self` with the given pointer
844    /// metadata.
845    ///
846    /// # Safety
847    ///
848    /// `size_for_metadata` promises to return `None` if and only if the
849    /// resulting size would not fit in a [`usize`]. Note that the returned size
850    /// could exceed the actual maximum valid size of an allocated object,
851    /// [`isize::MAX`].
852    ///
853    /// # Examples
854    ///
855    /// ```
856    /// use zerocopy::KnownLayout;
857    ///
858    /// assert_eq!(u8::size_for_metadata(()), Some(1));
859    /// assert_eq!(u16::size_for_metadata(()), Some(2));
860    /// assert_eq!(<[u8]>::size_for_metadata(42), Some(42));
861    /// assert_eq!(<[u16]>::size_for_metadata(42), Some(84));
862    ///
863    /// // This size exceeds the maximum valid object size (`isize::MAX`):
864    /// assert_eq!(<[u8]>::size_for_metadata(usize::MAX), Some(usize::MAX));
865    ///
866    /// // This size, if computed, would exceed `usize::MAX`:
867    /// assert_eq!(<[u16]>::size_for_metadata(usize::MAX), None);
868    /// ```
869    #[inline(always)]
870    fn size_for_metadata(meta: Self::PointerMetadata) -> Option<usize> {
871        meta.size_for_metadata(Self::LAYOUT)
872    }
873
874    /// Computes whether `meta` can describe a valid allocation of `Self`.
875    ///
876    /// # Safety
877    ///
878    /// `is_valid_metadata` promises to return `true` if and only if the size of
879    /// an allocation of `Self` with `meta` would not overflow an
880    /// [`isize::MAX`].
881    #[doc(hidden)]
882    #[inline(always)]
883    fn is_valid_metadata(meta: Self::PointerMetadata) -> bool {
884        meta.to_elem_count() <= maximum_trailing_slice_len::<Self>().to_elem_count()
885    }
886}
887
888/// Efficiently produces the [`TrailingSliceLayout`] of `T`.
889#[inline(always)]
890pub(crate) fn trailing_slice_layout<T>() -> TrailingSliceLayout
891where
892    T: ?Sized + KnownLayout<PointerMetadata = usize>,
893{
894    trait LayoutFacts {
895        const SIZE_INFO: TrailingSliceLayout;
896    }
897
898    impl<T: ?Sized> LayoutFacts for T
899    where
900        T: KnownLayout<PointerMetadata = usize>,
901    {
902        const SIZE_INFO: TrailingSliceLayout = match T::LAYOUT.size_info {
903            crate::SizeInfo::Sized { .. } => const_panic!("unreachable"),
904            crate::SizeInfo::SliceDst(info) => info,
905        };
906    }
907
908    T::SIZE_INFO
909}
910
911/// Efficiently produces the maximum trailing slice length `T`.
912#[inline(always)]
913pub(crate) fn maximum_trailing_slice_len<T>() -> usize
914where
915    T: ?Sized + KnownLayout,
916{
917    trait LayoutFacts {
918        const MAX_LEN: usize;
919    }
920
921    impl<T: ?Sized> LayoutFacts for T
922    where
923        T: KnownLayout,
924    {
925        const MAX_LEN: usize = match T::LAYOUT.size_info {
926            SizeInfo::SliceDst(TrailingSliceLayout { elem_size: 0, .. }) => usize::MAX,
927            _ => match T::LAYOUT.validate_cast_and_convert_metadata(
928                T::LAYOUT.align.get(),
929                DstLayout::MAX_SIZE,
930                CastType::Prefix,
931            ) {
932                Ok((elems, _)) => elems,
933                Err(_) => const_panic!("unreachable"),
934            },
935        };
936    }
937
938    T::MAX_LEN
939}
940
941/// The metadata associated with a [`KnownLayout`] type.
942#[doc(hidden)]
943pub trait PointerMetadata: Copy + Eq + Debug + Ord {
944    /// Constructs a `Self` from an element count.
945    ///
946    /// If `Self = ()`, this returns `()`. If `Self = usize`, this returns
947    /// `elems`. No other types are currently supported.
948    fn from_elem_count(elems: usize) -> Self;
949
950    /// Converts `self` to an element count.
951    ///
952    /// If `Self = ()`, this returns `0`. If `Self = usize`, this returns
953    /// `self`. No other types are currently supported.
954    fn to_elem_count(self) -> usize;
955
956    /// Computes the size of the object with the given layout and pointer
957    /// metadata.
958    ///
959    /// # Panics
960    ///
961    /// If `Self = ()`, `layout` must describe a sized type. If `Self = usize`,
962    /// `layout` must describe a slice DST. Otherwise, `size_for_metadata` may
963    /// panic.
964    ///
965    /// # Safety
966    ///
967    /// `size_for_metadata` promises to only return `None` if the resulting size
968    /// would not fit in a `usize`.
969    fn size_for_metadata(self, layout: DstLayout) -> Option<usize>;
970}
971
972impl PointerMetadata for () {
973    #[inline]
974    #[allow(clippy::unused_unit)]
975    fn from_elem_count(_elems: usize) -> () {}
976
977    #[inline]
978    fn to_elem_count(self) -> usize {
979        0
980    }
981
982    #[inline]
983    fn size_for_metadata(self, layout: DstLayout) -> Option<usize> {
984        match layout.size_info {
985            SizeInfo::Sized { size } => Some(size),
986            // NOTE: This branch is unreachable, but we return `None` rather
987            // than `unreachable!()` to avoid generating panic paths.
988            SizeInfo::SliceDst(_) => None,
989        }
990    }
991}
992
993impl PointerMetadata for usize {
994    #[inline]
995    fn from_elem_count(elems: usize) -> usize {
996        elems
997    }
998
999    #[inline]
1000    fn to_elem_count(self) -> usize {
1001        self
1002    }
1003
1004    #[inline]
1005    fn size_for_metadata(self, layout: DstLayout) -> Option<usize> {
1006        match layout.size_info {
1007            SizeInfo::SliceDst(TrailingSliceLayout { offset, elem_size }) => {
1008                let slice_len = elem_size.checked_mul(self)?;
1009                let without_padding = offset.checked_add(slice_len)?;
1010                without_padding.checked_add(util::padding_needed_for(without_padding, layout.align))
1011            }
1012            // NOTE: This branch is unreachable, but we return `None` rather
1013            // than `unreachable!()` to avoid generating panic paths.
1014            SizeInfo::Sized { .. } => None,
1015        }
1016    }
1017}
1018
1019// SAFETY: Delegates safety to `DstLayout::for_slice`.
1020unsafe impl<T> KnownLayout for [T] {
1021    #[allow(clippy::missing_inline_in_public_items, dead_code)]
1022    #[cfg_attr(
1023        all(coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS),
1024        coverage(off)
1025    )]
1026    fn only_derive_is_allowed_to_implement_this_trait()
1027    where
1028        Self: Sized,
1029    {
1030    }
1031
1032    type PointerMetadata = usize;
1033
1034    // SAFETY: `CoreMaybeUninit<T>::LAYOUT` and `T::LAYOUT` are identical
1035    // because `CoreMaybeUninit<T>` has the same size and alignment as `T` [1].
1036    // Consequently, `[CoreMaybeUninit<T>]::LAYOUT` and `[T]::LAYOUT` are
1037    // identical, because they both lack a fixed-sized prefix and because they
1038    // inherit the alignments of their inner element type (which are identical)
1039    // [2][3].
1040    //
1041    // `[CoreMaybeUninit<T>]` admits uninitialized bytes at all positions
1042    // because `CoreMaybeUninit<T>` admits uninitialized bytes at all positions
1043    // and because the inner elements of `[CoreMaybeUninit<T>]` are laid out
1044    // back-to-back [2][3].
1045    //
1046    // [1] Per https://doc.rust-lang.org/1.81.0/std/mem/union.MaybeUninit.html#layout-1:
1047    //
1048    //   `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as
1049    //   `T`
1050    //
1051    // [2] Per https://doc.rust-lang.org/1.82.0/reference/type-layout.html#slice-layout:
1052    //
1053    //   Slices have the same layout as the section of the array they slice.
1054    //
1055    // [3] Per https://doc.rust-lang.org/1.82.0/reference/type-layout.html#array-layout:
1056    //
1057    //   An array of `[T; N]` has a size of `size_of::<T>() * N` and the same
1058    //   alignment of `T`. Arrays are laid out so that the zero-based `nth`
1059    //   element of the array is offset from the start of the array by `n *
1060    //   size_of::<T>()` bytes.
1061    type MaybeUninit = [CoreMaybeUninit<T>];
1062
1063    const LAYOUT: DstLayout = DstLayout::for_slice::<T>();
1064
1065    // SAFETY: `.cast` preserves address and provenance. The returned pointer
1066    // refers to an object with `elems` elements by construction.
1067    #[inline(always)]
1068    fn raw_from_ptr_len(data: NonNull<u8>, elems: usize) -> NonNull<Self> {
1069        // FIXME(#67): Remove this allow. See NonNullExt for more details.
1070        #[allow(unstable_name_collisions)]
1071        NonNull::slice_from_raw_parts(data.cast::<T>(), elems)
1072    }
1073
1074    #[inline(always)]
1075    fn pointer_to_metadata(ptr: *mut [T]) -> usize {
1076        #[cfg(not(no_zerocopy_slice_ptr_len_1_79_0))]
1077        {
1078            ptr.len()
1079        }
1080
1081        #[cfg(no_zerocopy_slice_ptr_len_1_79_0)]
1082        {
1083            // `*mut [T]::len` was not stable before Rust 1.79. In every Rust
1084            // version from our 1.56 MSRV through 1.78, `Hash for *mut T`
1085            // decomposes a raw pointer and passes its address and metadata to
1086            // the hasher in that order [1]. `Hash for usize` passes its value
1087            // to `Hasher::write_usize` [2]. Capture those two values to obtain
1088            // a candidate for the slice length without dereferencing `ptr` or
1089            // constructing a reference.
1090            //
1091            // This historical `Hash` implementation is only used to produce a
1092            // candidate. Before returning it, we reconstruct a raw slice and
1093            // authenticate the candidate with `ptr::eq`, which compares slice
1094            // lengths as well as addresses [3]. Thus, an unexpected `Hash`
1095            // implementation cannot cause us to return incorrect metadata; it
1096            // can only fail to produce an authenticated candidate.
1097            //
1098            // [1] Per https://doc.rust-lang.org/1.56.0/src/core/hash/mod.rs.html#776-782:
1099            //
1100            //   let (address, metadata) = self.to_raw_parts();
1101            //   state.write_usize(address as usize);
1102            //   metadata.hash(state);
1103            //
1104            // [2] Per https://doc.rust-lang.org/1.56.0/src/core/hash/mod.rs.html#628-656:
1105            //
1106            //   fn hash<H: Hasher>(&self, state: &mut H) {
1107            //       state.$meth(*self)
1108            //   }
1109            //   ...
1110            //   (usize, write_usize),
1111            //
1112            // [3] Per https://doc.rust-lang.org/1.56.0/std/ptr/fn.eq.html:
1113            //
1114            //   Slices are also compared by their length (fat pointers).
1115            struct MetadataHasher {
1116                values: [usize; 2],
1117                writes: usize,
1118                valid: bool,
1119            }
1120
1121            impl Hasher for MetadataHasher {
1122                #[inline(always)]
1123                fn finish(&self) -> u64 {
1124                    0
1125                }
1126
1127                #[inline(always)]
1128                fn write(&mut self, _bytes: &[u8]) {
1129                    self.valid = false;
1130                }
1131
1132                #[inline(always)]
1133                fn write_usize(&mut self, value: usize) {
1134                    match self.values.get_mut(self.writes) {
1135                        Some(slot) => *slot = value,
1136                        None => self.valid = false,
1137                    }
1138                    self.writes = self.writes.saturating_add(1);
1139                }
1140            }
1141
1142            let mut hasher = MetadataHasher { values: [0; 2], writes: 0, valid: true };
1143            core::hash::Hash::hash(&ptr, &mut hasher);
1144            assert!(
1145                hasher.valid && hasher.writes == 2,
1146                "unexpected raw-pointer Hash implementation"
1147            );
1148
1149            let elems = hasher.values[1];
1150            #[allow(clippy::as_conversions)]
1151            let reconstructed = ptr::slice_from_raw_parts_mut(ptr as *mut T, elems);
1152            assert!(ptr::eq(ptr, reconstructed), "captured value is not raw-slice metadata");
1153            elems
1154        }
1155    }
1156}
1157
1158#[rustfmt::skip]
1159impl_known_layout!(
1160    (),
1161    u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64,
1162    bool, char,
1163    NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32,
1164    NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize
1165);
1166#[rustfmt::skip]
1167#[cfg(feature = "float-nightly")]
1168impl_known_layout!(
1169    #[cfg_attr(doc_cfg, doc(cfg(feature = "float-nightly")))]
1170    f16,
1171    #[cfg_attr(doc_cfg, doc(cfg(feature = "float-nightly")))]
1172    f128
1173);
1174#[rustfmt::skip]
1175impl_known_layout!(
1176    T         => Option<T>,
1177    T: ?Sized => PhantomData<T>,
1178    T         => Wrapping<T>,
1179    T         => CoreMaybeUninit<T>,
1180    T: ?Sized => *const T,
1181    T: ?Sized => *mut T,
1182    T: ?Sized => &'_ T,
1183    T: ?Sized => &'_ mut T,
1184);
1185impl_known_layout!(const N: usize, T => [T; N]);
1186
1187// SAFETY: `str` has the same representation as `[u8]`. `ManuallyDrop<T>` [1],
1188// `UnsafeCell<T>` [2], and `Cell<T>` [3] have the same representation as `T`.
1189//
1190// [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
1191//
1192//   `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
1193//   `T`
1194//
1195// [2] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.UnsafeCell.html#memory-layout:
1196//
1197//   `UnsafeCell<T>` has the same in-memory representation as its inner type
1198//   `T`.
1199//
1200// [3] Per https://doc.rust-lang.org/1.85.0/core/cell/struct.Cell.html#memory-layout:
1201//
1202//   `Cell<T>` has the same in-memory representation as `T`.
1203#[allow(clippy::multiple_unsafe_ops_per_block)]
1204const _: () = unsafe {
1205    unsafe_impl_known_layout!(
1206        #[repr([u8])]
1207        str
1208    );
1209    unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] ManuallyDrop<T>);
1210    unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] UnsafeCell<T>);
1211    unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] Cell<T>);
1212};
1213
1214// SAFETY:
1215// - By consequence of the invariant on `T::MaybeUninit` that `T::LAYOUT` and
1216//   `T::MaybeUninit::LAYOUT` are equal, `T` and `T::MaybeUninit` have the same:
1217//   - Fixed prefix size
1218//   - Alignment
1219//   - (For DSTs) trailing slice element size
1220// - By consequence of the above, referents `T::MaybeUninit` and `T` have the
1221//   require the same kind of pointer metadata, and thus it is valid to perform
1222//   an `as` cast from `*mut T` and `*mut T::MaybeUninit`, and this operation
1223//   preserves referent size (ie, `size_of_val_raw`).
1224const _: () = unsafe {
1225    unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T::MaybeUninit)] MaybeUninit<T>)
1226};
1227
1228// FIXME(#196, #2856): Eventually, we'll want to support enums variants and
1229// union fields being treated uniformly since they behave similarly to each
1230// other in terms of projecting validity – specifically, for a type `T` with
1231// validity `V`, if `T` is a struct type, then its fields straightforwardly also
1232// have validity `V`. By contrast, if `T` is an enum or union type, then
1233// validity is not straightforwardly recursive in this way.
1234#[doc(hidden)]
1235pub const STRUCT_VARIANT_ID: i128 = -1;
1236#[doc(hidden)]
1237pub const UNION_VARIANT_ID: i128 = -2;
1238#[doc(hidden)]
1239pub const REPR_C_UNION_VARIANT_ID: i128 = -3;
1240
1241/// Marker types used to disambiguate implementations of projection traits that
1242/// would otherwise conflict.
1243#[doc(hidden)]
1244#[allow(missing_copy_implementations, missing_debug_implementations)]
1245pub mod project_clients {
1246    pub enum TryFromBytesDerive {}
1247
1248    pub enum ProjectDerive {}
1249}
1250
1251#[cfg(any(feature = "derive", test))]
1252#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1253#[doc(hidden)]
1254pub use zerocopy_derive::Project;
1255
1256/// # Safety
1257///
1258/// `<Self as HasTag<Client>>::ProjectToTag` must satisfy its safety invariant.
1259///
1260/// The `Client` parameter exists solely to disambiguate between implementations
1261/// of `HasTag` that would otherwise conflict.
1262#[doc(hidden)]
1263pub unsafe trait HasTag<Client = project_clients::TryFromBytesDerive> {
1264    fn only_derive_is_allowed_to_implement_this_trait()
1265    where
1266        Self: Sized;
1267
1268    /// The type's enum tag, or `()` for non-enum types.
1269    type Tag: Immutable;
1270
1271    /// A pointer projection from `Self` to its tag.
1272    ///
1273    /// # Safety
1274    ///
1275    /// It must be the case that, for all `slf: Ptr<'_, Self, I>` where
1276    /// `I::Aliasing` is `Shared`, it is sound to project it using this
1277    /// projection to a `Ptr<'_, Self::Tag, (Shared, I::Alignment,
1278    /// I::Validity)>`.
1279    type ProjectToTag: pointer::cast::Project<Self, Self::Tag>;
1280}
1281
1282/// Projects a given field from `Self`.
1283///
1284/// All implementations of `HasField` for a particular `Client` and field `f`
1285/// in `Self` should use the same `Field` type; this ensures that `Field` is
1286/// inferable given an explicit `Client`, `VARIANT_ID`, and `FIELD_ID`.
1287///
1288/// The `Client` parameter exists solely to disambiguate between implementations
1289/// of `HasField` that would otherwise conflict.
1290///
1291/// # Safety
1292///
1293/// A field `f` is `HasField` for `Self` if and only if:
1294///
1295/// - If `Self` has the layout of a struct type, `VARIANT_ID` is
1296///   `STRUCT_VARIANT_ID`. If `Self` has the layout of a `repr(C)` union type,
1297///   `VARIANT_ID` is `REPR_C_UNION_VARIANT_ID`; for other union layouts, it is
1298///   `UNION_VARIANT_ID`. Otherwise, if `Self` has the layout of an enum type and
1299///   `f` appears in a variant named `v`, `VARIANT_ID` is
1300///   `zerocopy::ident_id!(v)`. Note that `Self` does not need to actually *be*
1301///   such a type – it just needs to have the same layout as such a type. For
1302///   example, a `#[repr(transparent)]` wrapper around an enum has the same
1303///   layout as that enum.
1304/// - If `f` has name `n`, `FIELD_ID` is `zerocopy::ident_id!(n)`; otherwise,
1305///   if `f` is at index `i`, `FIELD_ID` is `zerocopy::ident_id!(i)`.
1306/// - `Field` is a type with the same visibility as `f`.
1307/// - `Type` has the same type as `f`.
1308///
1309/// The caller must **not** assume that a pointer's referent being aligned
1310/// implies that calling `project` on that pointer will result in a pointer to
1311/// an aligned referent. For example, `HasField` may be implemented for
1312/// `#[repr(packed)]` structs.
1313///
1314/// The implementation of `project` must satisfy its safety post-condition.
1315#[doc(hidden)]
1316pub unsafe trait HasField<Client, Field, const VARIANT_ID: i128, const FIELD_ID: i128>:
1317    HasTag<Client>
1318{
1319    fn only_derive_is_allowed_to_implement_this_trait()
1320    where
1321        Self: Sized;
1322
1323    /// The type of the field.
1324    type Type: ?Sized;
1325
1326    /// Projects from `slf` to the field.
1327    ///
1328    /// Users should generally not call `project` directly, and instead should
1329    /// use high-level APIs like [`PtrInner::project`] or [`Ptr::project`].
1330    ///
1331    /// # Safety
1332    ///
1333    /// The returned pointer refers to a non-strict subset of the bytes of
1334    /// `slf`'s referent, and has the same provenance as `slf`.
1335    #[must_use]
1336    fn project(slf: PtrInner<'_, Self>) -> *mut Self::Type;
1337}
1338
1339/// Projects a given field from `Self`.
1340///
1341/// Implementations of this trait encode the conditions under which a field can
1342/// be projected from a `Ptr<'_, Self, I>`, and how the invariants of that
1343/// [`Ptr`] (`I`) determine the invariants of pointers projected from it. In
1344/// other words, it is a type-level function over invariants; `I` goes in,
1345/// `Self::Invariants` comes out.
1346///
1347/// The `Client` parameter exists solely to disambiguate between implementations
1348/// of `ProjectField` (and their corresponding `HasField` implementations) that
1349/// would otherwise conflict.
1350///
1351/// # Safety
1352///
1353/// `T: ProjectField<Client, Field, I, VARIANT_ID, FIELD_ID>` if, for a
1354/// `ptr: Ptr<'_, T, I>` such that `T::is_projectable` returns `Ok(())`
1355/// when passed the tag pointer projected from `ptr`,
1356/// `<T as HasField<Client, Field, VARIANT_ID, FIELD_ID>>::project(ptr.as_inner())`
1357/// conforms to `T::Invariants`.
1358#[doc(hidden)]
1359pub unsafe trait ProjectField<Client, Field, I, const VARIANT_ID: i128, const FIELD_ID: i128>:
1360    HasField<Client, Field, VARIANT_ID, FIELD_ID>
1361where
1362    I: invariant::Invariants,
1363{
1364    fn only_derive_is_allowed_to_implement_this_trait()
1365    where
1366        Self: Sized;
1367
1368    /// The invariants of the projected field pointer, with respect to the
1369    /// invariants, `I`, of the containing pointer. The aliasing dimension of
1370    /// the invariants is guaranteed to remain unchanged.
1371    type Invariants: invariant::Invariants<Aliasing = I::Aliasing>;
1372
1373    /// The failure mode of projection. `()` if the projection is fallible,
1374    /// otherwise [`core::convert::Infallible`].
1375    type Error;
1376
1377    /// Is the given field projectable from `ptr`?
1378    ///
1379    /// If a field with [`Self::Invariants`] is projectable from the containing
1380    /// value whose projected tag is `ptr`, this function produces `Ok(())`;
1381    /// otherwise it produces `Err`.
1382    ///
1383    /// This method must be overriden if the field's projectability depends on
1384    /// the value of the bytes in `ptr`.
1385    #[inline(always)]
1386    fn is_projectable<'a>(
1387        _ptr: Ptr<
1388            'a,
1389            <Self as HasTag<Client>>::Tag,
1390            (invariant::Shared, I::Alignment, I::Validity),
1391        >,
1392    ) -> Result<(), Self::Error> {
1393        trait IsInfallible {
1394            const IS_INFALLIBLE: bool;
1395        }
1396
1397        struct Projection<T, Client, Field, I, const VARIANT_ID: i128, const FIELD_ID: i128>(
1398            PhantomData<(Client, Field, I, T)>,
1399        )
1400        where
1401            T: ?Sized + HasField<Client, Field, VARIANT_ID, FIELD_ID>,
1402            I: invariant::Invariants;
1403
1404        impl<T, Client, Field, I, const VARIANT_ID: i128, const FIELD_ID: i128> IsInfallible
1405            for Projection<T, Client, Field, I, VARIANT_ID, FIELD_ID>
1406        where
1407            T: ?Sized + HasField<Client, Field, VARIANT_ID, FIELD_ID>,
1408            I: invariant::Invariants,
1409        {
1410            const IS_INFALLIBLE: bool = {
1411                let is_infallible = match VARIANT_ID {
1412                    // For nondestructive projections of struct and union
1413                    // fields, the projected field's satisfaction of
1414                    // `Invariants` does not depend on the value of the
1415                    // referent. This default implementation of `is_projectable`
1416                    // is non-destructive, as it does not overwrite any part of
1417                    // the referent.
1418                    crate::STRUCT_VARIANT_ID
1419                    | crate::UNION_VARIANT_ID
1420                    | crate::REPR_C_UNION_VARIANT_ID => true,
1421                    _enum_variant => {
1422                        use crate::invariant::{Validity, ValidityKind};
1423                        match I::Validity::KIND {
1424                            // The `Uninit` and `Initialized` validity
1425                            // invariants do not depend on the enum's tag. In
1426                            // particular, we don't actually care about what
1427                            // variant is present – we can treat *any* range of
1428                            // uninitialized or initialized memory as containing
1429                            // an uninitialized or initialized instance of *any*
1430                            // type – the type itself is irrelevant.
1431                            ValidityKind::Uninit | ValidityKind::Initialized => true,
1432                            // The projectability of an enum field from an
1433                            // `AsInitialized` or `Safe` state is a dynamic
1434                            // property of its tag.
1435                            ValidityKind::AsInitialized | ValidityKind::Safe => false,
1436                        }
1437                    }
1438                };
1439                const_assert!(is_infallible);
1440                is_infallible
1441            };
1442        }
1443
1444        const_assert!(
1445            <Projection<Self, Client, Field, I, VARIANT_ID, FIELD_ID> as IsInfallible>::IS_INFALLIBLE
1446        );
1447
1448        Ok(())
1449    }
1450}
1451
1452/// Analyzes whether a type is [`FromZeros`].
1453///
1454/// This derive analyzes, at compile time, whether the annotated type satisfies
1455/// the [safety conditions] of `FromZeros` and implements `FromZeros` and its
1456/// supertraits if it is sound to do so. This derive can be applied to structs,
1457/// enums, and unions; e.g.:
1458///
1459/// ```
1460/// # use zerocopy_derive::{FromZeros, Immutable};
1461/// #[derive(FromZeros)]
1462/// struct MyStruct {
1463/// # /*
1464///     ...
1465/// # */
1466/// }
1467///
1468/// #[derive(FromZeros)]
1469/// #[repr(u8)]
1470/// enum MyEnum {
1471/// #   Variant0,
1472/// # /*
1473///     ...
1474/// # */
1475/// }
1476///
1477/// #[derive(FromZeros, Immutable)]
1478/// union MyUnion {
1479/// #   variant: u8,
1480/// # /*
1481///     ...
1482/// # */
1483/// }
1484/// ```
1485///
1486/// [safety conditions]: trait@FromZeros#safety
1487///
1488/// # Analysis
1489///
1490/// *This section describes, roughly, the analysis performed by this derive to
1491/// determine whether it is sound to implement `FromZeros` for a given type.
1492/// Unless you are modifying the implementation of this derive, or attempting to
1493/// manually implement `FromZeros` for a type yourself, you don't need to read
1494/// this section.*
1495///
1496/// If a type has the following properties, then this derive can implement
1497/// `FromZeros` for that type:
1498///
1499/// - If the type is a struct, all of its fields must be `FromZeros`.
1500/// - If the type is an enum:
1501///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
1502///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
1503///   - It must have a variant with a discriminant/tag of `0`, and its fields
1504///     must be `FromZeros`. See [the reference] for a description of
1505///     discriminant values are specified.
1506///   - The fields of that variant must be `FromZeros`.
1507///
1508/// This analysis is subject to change. Unsafe code may *only* rely on the
1509/// documented [safety conditions] of `FromZeros`, and must *not* rely on the
1510/// implementation details of this derive.
1511///
1512/// [the reference]: https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
1513///
1514/// ## Why isn't an explicit representation required for structs?
1515///
1516/// Neither this derive, nor the [safety conditions] of `FromZeros`, requires
1517/// that structs are marked with `#[repr(C)]`.
1518///
1519/// Per the [Rust reference](reference),
1520///
1521/// > The representation of a type can change the padding between fields, but
1522/// > does not change the layout of the fields themselves.
1523///
1524/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
1525///
1526/// Since the layout of structs only consists of padding bytes and field bytes,
1527/// a struct is soundly `FromZeros` if:
1528/// 1. its padding is soundly `FromZeros`, and
1529/// 2. its fields are soundly `FromZeros`.
1530///
1531/// The answer to the first question is always yes: padding bytes do not have
1532/// any validity constraints. A [discussion] of this question in the Unsafe Code
1533/// Guidelines Working Group concluded that it would be virtually unimaginable
1534/// for future versions of rustc to add validity constraints to padding bytes.
1535///
1536/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
1537///
1538/// Whether a struct is soundly `FromZeros` therefore solely depends on whether
1539/// its fields are `FromZeros`.
1540// FIXME(#146): Document why we don't require an enum to have an explicit `repr`
1541// attribute.
1542#[cfg(any(feature = "derive", test))]
1543#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1544pub use zerocopy_derive::FromZeros;
1545/// Analyzes whether a type is [`Immutable`].
1546///
1547/// This derive analyzes, at compile time, whether the annotated type satisfies
1548/// the [safety conditions] of `Immutable` and implements `Immutable` if it is
1549/// sound to do so. This derive can be applied to structs, enums, and unions;
1550/// e.g.:
1551///
1552/// ```
1553/// # use zerocopy_derive::Immutable;
1554/// #[derive(Immutable)]
1555/// struct MyStruct {
1556/// # /*
1557///     ...
1558/// # */
1559/// }
1560///
1561/// #[derive(Immutable)]
1562/// enum MyEnum {
1563/// #   Variant0,
1564/// # /*
1565///     ...
1566/// # */
1567/// }
1568///
1569/// #[derive(Immutable)]
1570/// union MyUnion {
1571/// #   variant: u8,
1572/// # /*
1573///     ...
1574/// # */
1575/// }
1576/// ```
1577///
1578/// # Analysis
1579///
1580/// *This section describes, roughly, the analysis performed by this derive to
1581/// determine whether it is sound to implement `Immutable` for a given type.
1582/// Unless you are modifying the implementation of this derive, you don't need
1583/// to read this section.*
1584///
1585/// If a type has the following properties, then this derive can implement
1586/// `Immutable` for that type:
1587///
1588/// - All fields must be `Immutable`.
1589///
1590/// This analysis is subject to change. Unsafe code may *only* rely on the
1591/// documented [safety conditions] of `Immutable`, and must *not* rely on the
1592/// implementation details of this derive.
1593///
1594/// [safety conditions]: trait@Immutable#safety
1595#[cfg(any(feature = "derive", test))]
1596#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1597pub use zerocopy_derive::Immutable;
1598
1599/// Types which are free from interior mutability.
1600///
1601/// `T: Immutable` indicates that `T` does not permit interior mutation, except
1602/// by ownership or an exclusive (`&mut`) borrow.
1603///
1604/// # Implementation
1605///
1606/// **Do not implement this trait yourself!** Instead, use
1607/// [`#[derive(Immutable)]`][derive] (requires the `derive` Cargo feature);
1608/// e.g.:
1609///
1610/// ```
1611/// # use zerocopy_derive::Immutable;
1612/// #[derive(Immutable)]
1613/// struct MyStruct {
1614/// # /*
1615///     ...
1616/// # */
1617/// }
1618///
1619/// #[derive(Immutable)]
1620/// enum MyEnum {
1621/// # /*
1622///     ...
1623/// # */
1624/// }
1625///
1626/// #[derive(Immutable)]
1627/// union MyUnion {
1628/// #   variant: u8,
1629/// # /*
1630///     ...
1631/// # */
1632/// }
1633/// ```
1634///
1635/// This derive performs a sophisticated, compile-time safety analysis to
1636/// determine whether a type is `Immutable`.
1637///
1638/// # Safety
1639///
1640/// Unsafe code outside of this crate must not make any assumptions about `T`
1641/// based on `T: Immutable`. We reserve the right to relax the requirements for
1642/// `Immutable` in the future, and if unsafe code outside of this crate makes
1643/// assumptions based on `T: Immutable`, future relaxations may cause that code
1644/// to become unsound.
1645///
1646// # Safety (Internal)
1647//
1648// If `T: Immutable`, unsafe code *inside of this crate* may assume that, given
1649// `t: &T`, `t` does not permit interior mutation of its referent. Because
1650// [`UnsafeCell`] is the only type which permits interior mutation, it is
1651// sufficient (though not necessary) to guarantee that `T` contains no
1652// `UnsafeCell`s.
1653//
1654// [`UnsafeCell`]: core::cell::UnsafeCell
1655#[cfg_attr(
1656    feature = "derive",
1657    doc = "[derive]: zerocopy_derive::Immutable",
1658    doc = "[derive-analysis]: zerocopy_derive::Immutable#analysis"
1659)]
1660#[cfg_attr(
1661    not(feature = "derive"),
1662    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.Immutable.html"),
1663    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.Immutable.html#analysis"),
1664)]
1665#[cfg_attr(
1666    not(no_zerocopy_diagnostic_on_unimplemented_1_78_0),
1667    diagnostic::on_unimplemented(note = "Consider adding `#[derive(Immutable)]` to `{Self}`")
1668)]
1669pub unsafe trait Immutable {
1670    // The `Self: Sized` bound makes it so that `Immutable` is still object
1671    // safe.
1672    #[doc(hidden)]
1673    fn only_derive_is_allowed_to_implement_this_trait()
1674    where
1675        Self: Sized;
1676}
1677
1678/// Implements [`TryFromBytes`].
1679///
1680/// This derive synthesizes the runtime checks required to check whether a
1681/// sequence of initialized bytes corresponds to a valid instance of a type.
1682/// This derive can be applied to structs, enums, and unions; e.g.:
1683///
1684/// ```
1685/// # use zerocopy_derive::{TryFromBytes, Immutable};
1686/// #[derive(TryFromBytes)]
1687/// struct MyStruct {
1688/// # /*
1689///     ...
1690/// # */
1691/// }
1692///
1693/// #[derive(TryFromBytes)]
1694/// #[repr(u8)]
1695/// enum MyEnum {
1696/// #   V00,
1697/// # /*
1698///     ...
1699/// # */
1700/// }
1701///
1702/// #[derive(TryFromBytes, Immutable)]
1703/// union MyUnion {
1704/// #   variant: u8,
1705/// # /*
1706///     ...
1707/// # */
1708/// }
1709/// ```
1710///
1711#[cfg_attr(
1712    zerocopy_unstable_ptr,
1713    doc = r#"
1714# Field invariants
1715
1716This experimental feature requires `--cfg zerocopy_unstable_ptr`.
1717
1718Named fields of structs, enum variants, and unions can specify additional
1719runtime checks using `#[zerocopy(invariant(expression))]`:
1720
1721```
1722# use zerocopy_derive::TryFromBytes;
1723#[derive(TryFromBytes)]
1724struct Foo {
1725    a: u8,
1726    #[zerocopy(invariant((*a.read() % 2) == (*b.read() as u8)))]
1727    b: bool,
1728    #[zerocopy(invariant(*c.read() > 0))]
1729    c: i16,
1730}
1731```
1732
1733Each expression must return a `bool`. It has access to validated, read-only
1734[`Ptr`]s to the current field and all preceding fields of the struct or
1735variant, using their field names. A union's invariants have access only to
1736the current field. The expression can use the existing [`Ptr`] APIs to
1737inspect those fields. In this example, `read()` copies each field without
1738requiring alignment, and dereferencing the resulting [`ReadOnly`] accesses
1739the copied value.
1740
1741Rust's usual restrictions on local bindings apply; for example, a field name
1742cannot shadow an in-scope constant.
1743
1744Fields are checked in declaration order. Each field's bit validity is
1745checked before its invariants run. Multiple invariants on a field run in
1746attribute order. For structs and enums, validation stops at the first invalid
1747field or invariant that returns `false`. For unions, a failed bit-validity
1748check or invariant causes validation to try the next field; validation
1749succeeds as soon as one field and all its invariants pass. Each expression
1750runs in its own closure; `return` returns from that expression, and panics
1751propagate to the caller. Only the selected enum variant's fields and
1752invariants are checked. Expressions may have arbitrary side effects, even
1753when the conversion fails or its result is discarded.
1754
1755These predicates are additional acceptance checks beyond Rust's bit validity;
1756bit-valid bytes may still be rejected. See [What is a "valid instance"?] for
1757the distinction.
1758
1759[What is a "valid instance"?]: trait@TryFromBytes#what-is-a-valid-instance
1760
1761Invariants are not supported on tuple fields. Types with invariants cannot
1762derive [`FromZeros`] or [`FromBytes`], whose conversions do not perform runtime
1763validation. These checks apply to conversions through [`TryFromBytes`]; they
1764do not restrict ordinary construction or mutation of Rust values.
1765
1766"#
1767)]
1768///
1769/// # Portability
1770///
1771/// To ensure consistent endianness for enums with multi-byte representations,
1772/// explicitly specify and convert each discriminant using `.to_le()` or
1773/// `.to_be()`; e.g.:
1774///
1775/// ```
1776/// # use zerocopy_derive::TryFromBytes;
1777/// // `DataStoreVersion` is encoded in little-endian.
1778/// #[derive(TryFromBytes)]
1779/// #[repr(u32)]
1780/// pub enum DataStoreVersion {
1781///     /// Version 1 of the data store.
1782///     V1 = 9u32.to_le(),
1783///
1784///     /// Version 2 of the data store.
1785///     V2 = 10u32.to_le(),
1786/// }
1787/// ```
1788///
1789/// [safety conditions]: trait@TryFromBytes#safety
1790#[cfg(any(feature = "derive", test))]
1791#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1792pub use zerocopy_derive::TryFromBytes;
1793
1794/// Types for which some bit patterns are valid.
1795///
1796/// A memory region of the appropriate length which contains initialized bytes
1797/// can be viewed as a `TryFromBytes` type so long as the runtime value of those
1798/// bytes corresponds to a [*valid instance*] of that type. For example,
1799/// [`bool`] is `TryFromBytes`, so zerocopy can transmute a [`u8`] into a
1800/// [`bool`] so long as it first checks that the value of the [`u8`] is `0` or
1801/// `1`.
1802///
1803/// # Implementation
1804///
1805/// **Do not implement this trait yourself!** Instead, use
1806/// [`#[derive(TryFromBytes)]`][derive]; e.g.:
1807///
1808/// ```
1809/// # use zerocopy_derive::{TryFromBytes, Immutable};
1810/// #[derive(TryFromBytes)]
1811/// struct MyStruct {
1812/// # /*
1813///     ...
1814/// # */
1815/// }
1816///
1817/// #[derive(TryFromBytes)]
1818/// #[repr(u8)]
1819/// enum MyEnum {
1820/// #   V00,
1821/// # /*
1822///     ...
1823/// # */
1824/// }
1825///
1826/// #[derive(TryFromBytes, Immutable)]
1827/// union MyUnion {
1828/// #   variant: u8,
1829/// # /*
1830///     ...
1831/// # */
1832/// }
1833/// ```
1834///
1835/// This derive ensures that the runtime check of whether bytes correspond to a
1836/// valid instance is sound. You **must** implement this trait via the derive.
1837///
1838/// # What is a "valid instance"?
1839///
1840/// In Rust, each type has *bit validity*, which refers to the set of bit
1841/// patterns which may appear in an instance of that type. It is impossible for
1842/// safe Rust code to produce values which violate bit validity (ie, values
1843/// outside of the "valid" set of bit patterns). If `unsafe` code produces an
1844/// invalid value, this is considered [undefined behavior].
1845///
1846/// Rust's bit validity rules are currently being decided, which means that some
1847/// types have three classes of bit patterns: those which are definitely valid,
1848/// and whose validity is documented in the language; those which may or may not
1849/// be considered valid at some point in the future; and those which are
1850/// definitely invalid.
1851///
1852/// Zerocopy takes a conservative approach, and only considers a bit pattern to
1853/// be valid if its validity is a documented guarantee provided by the
1854/// language.
1855///
1856/// For most use cases, Rust's current guarantees align with programmers'
1857/// intuitions about what ought to be valid. As a result, zerocopy's
1858/// conservatism should not affect most users.
1859///
1860/// If you are negatively affected by lack of support for a particular type,
1861/// we encourage you to let us know by [filing an issue][github-repo].
1862///
1863/// In this trait's conversion methods, a "valid instance" must also pass any
1864/// configured field invariants, including those on nested fields. Rust bit
1865/// validity alone does not guarantee that a conversion succeeds: an invariant
1866/// may reject otherwise bit-valid bytes. Such predicates check acceptance at
1867/// conversion time; they do not constrain subsequent mutation or ordinary Rust
1868/// construction. See the [derive's field invariants][derive] documentation for
1869/// the experimental attribute's syntax, evaluation order, and side effects.
1870///
1871/// # `TryFromBytes` is not symmetrical with [`IntoBytes`]
1872///
1873/// There are some types which implement both `TryFromBytes` and [`IntoBytes`],
1874/// but for which `TryFromBytes` is not guaranteed to accept all byte sequences
1875/// produced by `IntoBytes`. In other words, for some `T: TryFromBytes +
1876/// IntoBytes`, there exist values of `t: T` such that
1877/// `TryFromBytes::try_ref_from_bytes(t.as_bytes()) == None`. Code should not
1878/// generally assume that values produced by `IntoBytes` will necessarily be
1879/// accepted as valid by `TryFromBytes`.
1880///
1881/// # Safety
1882///
1883/// On its own, `T: TryFromBytes` does not make any guarantees about the layout
1884/// or representation of `T`. It merely provides the ability to perform a
1885/// validity check at runtime via methods like [`try_ref_from_bytes`].
1886///
1887/// You must not rely on the `#[doc(hidden)]` internals of `TryFromBytes`.
1888/// Future releases of zerocopy may make backwards-breaking changes to these
1889/// items, including changes that only affect soundness, which may cause code
1890/// which uses those items to silently become unsound.
1891///
1892/// [undefined behavior]: https://raphlinus.github.io/programming/rust/2018/08/17/undefined-behavior.html
1893/// [github-repo]: https://github.com/google/zerocopy
1894/// [`try_ref_from_bytes`]: TryFromBytes::try_ref_from_bytes
1895/// [*valid instance*]: #what-is-a-valid-instance
1896#[cfg_attr(feature = "derive", doc = "[derive]: zerocopy_derive::TryFromBytes")]
1897#[cfg_attr(
1898    not(feature = "derive"),
1899    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.TryFromBytes.html"),
1900)]
1901#[cfg_attr(
1902    not(no_zerocopy_diagnostic_on_unimplemented_1_78_0),
1903    diagnostic::on_unimplemented(note = "Consider adding `#[derive(TryFromBytes)]` to `{Self}`")
1904)]
1905pub unsafe trait TryFromBytes {
1906    // The `Self: Sized` bound makes it so that `TryFromBytes` is still object
1907    // safe.
1908    #[doc(hidden)]
1909    fn only_derive_is_allowed_to_implement_this_trait()
1910    where
1911        Self: Sized;
1912
1913    /// Does a given memory range contain a valid instance of `Self`?
1914    ///
1915    /// # Safety
1916    ///
1917    /// Unsafe code may assume that, if `is_safe(candidate)` returns true,
1918    /// `*candidate` contains a valid `Self`.
1919    ///
1920    /// # Panics
1921    ///
1922    /// `is_safe` may panic. Callers are responsible for ensuring that any
1923    /// `unsafe` code remains sound even in the face of `is_safe` panicking. (We
1924    /// support user-defined validation routines; so long as these routines are
1925    /// not required to be `unsafe`, there is no way to ensure that these do not
1926    /// generate panics.)
1927    ///
1928    /// Besides user-defined validation routines panicking, `is_safe` will either
1929    /// panic or fail to compile if called on a pointer with [`Shared`] aliasing
1930    /// when `Self: !Immutable`.
1931    ///
1932    /// [`UnsafeCell`]: core::cell::UnsafeCell
1933    /// [`Shared`]: invariant::Shared
1934    #[doc(hidden)]
1935    fn is_safe<A>(candidate: Maybe<'_, Self, A>) -> bool
1936    where
1937        A: invariant::Alignment;
1938
1939    /// Attempts to interpret the given `source` as a `&Self`.
1940    ///
1941    /// If the bytes of `source` are a valid instance of `Self`, this method
1942    /// returns a reference to those bytes interpreted as a `Self`. If the
1943    /// length of `source` is not a [valid size of `Self`][valid-size], or if
1944    /// `source` is not appropriately aligned, or if `source` is not a valid
1945    /// instance of `Self`, this returns `Err`. If [`Self:
1946    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
1947    /// error][ConvertError::from].
1948    ///
1949    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
1950    ///
1951    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
1952    /// [self-unaligned]: Unaligned
1953    /// [slice-dst]: KnownLayout#dynamically-sized-types
1954    ///
1955    /// # Compile-Time Assertions
1956    ///
1957    /// This method cannot yet be used on unsized types whose dynamically-sized
1958    /// component is zero-sized. Attempting to use this method on such types
1959    /// results in a compile-time assertion error; e.g.:
1960    ///
1961    /// ```compile_fail,E0080
1962    /// use zerocopy::*;
1963    /// # use zerocopy_derive::*;
1964    ///
1965    /// #[derive(TryFromBytes, Immutable, KnownLayout)]
1966    /// #[repr(C)]
1967    /// struct ZSTy {
1968    ///     leading_sized: u16,
1969    ///     trailing_dst: [()],
1970    /// }
1971    ///
1972    /// let _ = ZSTy::try_ref_from_bytes(0u16.as_bytes()); // âš  Compile Error!
1973    /// ```
1974    ///
1975    /// # Examples
1976    ///
1977    /// ```
1978    /// use zerocopy::TryFromBytes;
1979    /// # use zerocopy_derive::*;
1980    ///
1981    /// // The only valid value of this type is the byte `0xC0`
1982    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
1983    /// #[repr(u8)]
1984    /// enum C0 { xC0 = 0xC0 }
1985    ///
1986    /// // The only valid value of this type is the byte sequence `0xC0C0`.
1987    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
1988    /// #[repr(C)]
1989    /// struct C0C0(C0, C0);
1990    ///
1991    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
1992    /// #[repr(C)]
1993    /// struct Packet {
1994    ///     magic_number: C0C0,
1995    ///     mug_size: u8,
1996    ///     temperature: u8,
1997    ///     marshmallows: [[u8; 2]],
1998    /// }
1999    ///
2000    /// let bytes = &[0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5][..];
2001    ///
2002    /// let packet = Packet::try_ref_from_bytes(bytes).unwrap();
2003    ///
2004    /// assert_eq!(packet.mug_size, 240);
2005    /// assert_eq!(packet.temperature, 77);
2006    /// assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);
2007    ///
2008    /// // These bytes are not valid instance of `Packet`.
2009    /// let bytes = &[0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5][..];
2010    /// assert!(Packet::try_ref_from_bytes(bytes).is_err());
2011    /// ```
2012    ///
2013    #[doc = codegen_section!(
2014        header = "h5",
2015        bench = "try_ref_from_bytes",
2016        format = "coco",
2017        arity = 3,
2018        [
2019            open
2020            @index 1
2021            @title "Sized"
2022            @variant "static_size"
2023        ],
2024        [
2025            @index 2
2026            @title "Unsized"
2027            @variant "dynamic_size"
2028        ],
2029        [
2030            @index 3
2031            @title "Dynamically Padded"
2032            @variant "dynamic_padding"
2033        ]
2034    )]
2035    #[must_use = "the conversion result must be checked"]
2036    #[cfg_attr(zerocopy_inline_always, inline(always))]
2037    #[cfg_attr(not(zerocopy_inline_always), inline)]
2038    fn try_ref_from_bytes(source: &[u8]) -> Result<&Self, TryCastError<&[u8], Self>>
2039    where
2040        Self: KnownLayout + Immutable,
2041    {
2042        static_assert_dst_is_not_zst!(Self);
2043        match Ptr::from_ref(source).try_cast_into_no_leftover::<Self, BecauseImmutable>(None) {
2044            Ok(source) => {
2045                // This call may panic. If that happens, it doesn't cause any soundness
2046                // issues, as we have not generated any invalid state which we need to
2047                // fix before returning.
2048                match source.try_into_safe() {
2049                    Ok(valid) => Ok(valid.as_ref()),
2050                    Err(e) => {
2051                        Err(e.map_src(|src| src.as_bytes::<BecauseImmutable>().as_ref()).into())
2052                    }
2053                }
2054            }
2055            Err(e) => Err(e.map_src(Ptr::as_ref).into()),
2056        }
2057    }
2058
2059    /// Attempts to interpret the prefix of the given `source` as a `&Self`.
2060    ///
2061    /// This method computes the [largest possible size of `Self`][valid-size]
2062    /// that can fit in the leading bytes of `source`. If that prefix is a valid
2063    /// instance of `Self`, this method returns a reference to those bytes
2064    /// interpreted as `Self`, and a reference to the remaining bytes. If there
2065    /// are insufficient bytes, or if `source` is not appropriately aligned, or
2066    /// if those bytes are not a valid instance of `Self`, this returns `Err`.
2067    /// If [`Self: Unaligned`][self-unaligned], you can [infallibly discard the
2068    /// alignment error][ConvertError::from].
2069    ///
2070    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
2071    ///
2072    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
2073    /// [self-unaligned]: Unaligned
2074    /// [slice-dst]: KnownLayout#dynamically-sized-types
2075    ///
2076    /// # Compile-Time Assertions
2077    ///
2078    /// This method cannot yet be used on unsized types whose dynamically-sized
2079    /// component is zero-sized. Attempting to use this method on such types
2080    /// results in a compile-time assertion error; e.g.:
2081    ///
2082    /// ```compile_fail,E0080
2083    /// use zerocopy::*;
2084    /// # use zerocopy_derive::*;
2085    ///
2086    /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2087    /// #[repr(C)]
2088    /// struct ZSTy {
2089    ///     leading_sized: u16,
2090    ///     trailing_dst: [()],
2091    /// }
2092    ///
2093    /// let _ = ZSTy::try_ref_from_prefix(0u16.as_bytes()); // âš  Compile Error!
2094    /// ```
2095    ///
2096    /// # Examples
2097    ///
2098    /// ```
2099    /// use zerocopy::TryFromBytes;
2100    /// # use zerocopy_derive::*;
2101    ///
2102    /// // The only valid value of this type is the byte `0xC0`
2103    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2104    /// #[repr(u8)]
2105    /// enum C0 { xC0 = 0xC0 }
2106    ///
2107    /// // The only valid value of this type is the bytes `0xC0C0`.
2108    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2109    /// #[repr(C)]
2110    /// struct C0C0(C0, C0);
2111    ///
2112    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2113    /// #[repr(C)]
2114    /// struct Packet {
2115    ///     magic_number: C0C0,
2116    ///     mug_size: u8,
2117    ///     temperature: u8,
2118    ///     marshmallows: [[u8; 2]],
2119    /// }
2120    ///
2121    /// // These are more bytes than are needed to encode a `Packet`.
2122    /// let bytes = &[0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
2123    ///
2124    /// let (packet, suffix) = Packet::try_ref_from_prefix(bytes).unwrap();
2125    ///
2126    /// assert_eq!(packet.mug_size, 240);
2127    /// assert_eq!(packet.temperature, 77);
2128    /// assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);
2129    /// assert_eq!(suffix, &[6u8][..]);
2130    ///
2131    /// // These bytes are not valid instance of `Packet`.
2132    /// let bytes = &[0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
2133    /// assert!(Packet::try_ref_from_prefix(bytes).is_err());
2134    /// ```
2135    ///
2136    #[doc = codegen_section!(
2137        header = "h5",
2138        bench = "try_ref_from_prefix",
2139        format = "coco",
2140        arity = 3,
2141        [
2142            open
2143            @index 1
2144            @title "Sized"
2145            @variant "static_size"
2146        ],
2147        [
2148            @index 2
2149            @title "Unsized"
2150            @variant "dynamic_size"
2151        ],
2152        [
2153            @index 3
2154            @title "Dynamically Padded"
2155            @variant "dynamic_padding"
2156        ]
2157    )]
2158    #[must_use = "the conversion result must be checked"]
2159    #[cfg_attr(zerocopy_inline_always, inline(always))]
2160    #[cfg_attr(not(zerocopy_inline_always), inline)]
2161    fn try_ref_from_prefix(source: &[u8]) -> Result<(&Self, &[u8]), TryCastError<&[u8], Self>>
2162    where
2163        Self: KnownLayout + Immutable,
2164    {
2165        static_assert_dst_is_not_zst!(Self);
2166        try_ref_from_prefix_suffix(source, CastType::Prefix, None)
2167    }
2168
2169    /// Attempts to interpret the suffix of the given `source` as a `&Self`.
2170    ///
2171    /// This method computes the [largest possible size of `Self`][valid-size]
2172    /// that can fit in the trailing bytes of `source`. If that suffix is a
2173    /// valid instance of `Self`, this method returns a reference to those bytes
2174    /// interpreted as `Self`, and a reference to the preceding bytes. If there
2175    /// are insufficient bytes, or if the suffix of `source` would not be
2176    /// appropriately aligned, or if the suffix is not a valid instance of
2177    /// `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned], you
2178    /// can [infallibly discard the alignment error][ConvertError::from].
2179    ///
2180    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
2181    ///
2182    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
2183    /// [self-unaligned]: Unaligned
2184    /// [slice-dst]: KnownLayout#dynamically-sized-types
2185    ///
2186    /// # Compile-Time Assertions
2187    ///
2188    /// This method cannot yet be used on unsized types whose dynamically-sized
2189    /// component is zero-sized. Attempting to use this method on such types
2190    /// results in a compile-time assertion error; e.g.:
2191    ///
2192    /// ```compile_fail,E0080
2193    /// use zerocopy::*;
2194    /// # use zerocopy_derive::*;
2195    ///
2196    /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2197    /// #[repr(C)]
2198    /// struct ZSTy {
2199    ///     leading_sized: u16,
2200    ///     trailing_dst: [()],
2201    /// }
2202    ///
2203    /// let _ = ZSTy::try_ref_from_suffix(0u16.as_bytes()); // âš  Compile Error!
2204    /// ```
2205    ///
2206    /// # Examples
2207    ///
2208    /// ```
2209    /// use zerocopy::TryFromBytes;
2210    /// # use zerocopy_derive::*;
2211    ///
2212    /// // The only valid value of this type is the byte `0xC0`
2213    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2214    /// #[repr(u8)]
2215    /// enum C0 { xC0 = 0xC0 }
2216    ///
2217    /// // The only valid value of this type is the bytes `0xC0C0`.
2218    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2219    /// #[repr(C)]
2220    /// struct C0C0(C0, C0);
2221    ///
2222    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2223    /// #[repr(C)]
2224    /// struct Packet {
2225    ///     magic_number: C0C0,
2226    ///     mug_size: u8,
2227    ///     temperature: u8,
2228    ///     marshmallows: [[u8; 2]],
2229    /// }
2230    ///
2231    /// // These are more bytes than are needed to encode a `Packet`.
2232    /// let bytes = &[0, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
2233    ///
2234    /// let (prefix, packet) = Packet::try_ref_from_suffix(bytes).unwrap();
2235    ///
2236    /// assert_eq!(packet.mug_size, 240);
2237    /// assert_eq!(packet.temperature, 77);
2238    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2239    /// assert_eq!(prefix, &[0u8][..]);
2240    ///
2241    /// // These bytes are not valid instance of `Packet`.
2242    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0x10][..];
2243    /// assert!(Packet::try_ref_from_suffix(bytes).is_err());
2244    /// ```
2245    ///
2246    #[doc = codegen_section!(
2247        header = "h5",
2248        bench = "try_ref_from_suffix",
2249        format = "coco",
2250        arity = 3,
2251        [
2252            open
2253            @index 1
2254            @title "Sized"
2255            @variant "static_size"
2256        ],
2257        [
2258            @index 2
2259            @title "Unsized"
2260            @variant "dynamic_size"
2261        ],
2262        [
2263            @index 3
2264            @title "Dynamically Padded"
2265            @variant "dynamic_padding"
2266        ]
2267    )]
2268    #[must_use = "the conversion result must be checked"]
2269    #[cfg_attr(zerocopy_inline_always, inline(always))]
2270    #[cfg_attr(not(zerocopy_inline_always), inline)]
2271    fn try_ref_from_suffix(source: &[u8]) -> Result<(&[u8], &Self), TryCastError<&[u8], Self>>
2272    where
2273        Self: KnownLayout + Immutable,
2274    {
2275        static_assert_dst_is_not_zst!(Self);
2276        try_ref_from_prefix_suffix(source, CastType::Suffix, None).map(swap)
2277    }
2278
2279    /// Attempts to interpret the given `source` as a `&mut Self` without
2280    /// copying.
2281    ///
2282    /// If the bytes of `source` are a valid instance of `Self`, this method
2283    /// returns a reference to those bytes interpreted as a `Self`. If the
2284    /// length of `source` is not a [valid size of `Self`][valid-size], or if
2285    /// `source` is not appropriately aligned, or if `source` is not a valid
2286    /// instance of `Self`, this returns `Err`. If [`Self:
2287    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
2288    /// error][ConvertError::from].
2289    ///
2290    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
2291    ///
2292    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
2293    /// [self-unaligned]: Unaligned
2294    /// [slice-dst]: KnownLayout#dynamically-sized-types
2295    ///
2296    /// # Compile-Time Assertions
2297    ///
2298    /// This method cannot yet be used on unsized types whose dynamically-sized
2299    /// component is zero-sized. Attempting to use this method on such types
2300    /// results in a compile-time assertion error; e.g.:
2301    ///
2302    /// ```compile_fail,E0080
2303    /// use zerocopy::*;
2304    /// # use zerocopy_derive::*;
2305    ///
2306    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2307    /// #[repr(C, packed)]
2308    /// struct ZSTy {
2309    ///     leading_sized: [u8; 2],
2310    ///     trailing_dst: [()],
2311    /// }
2312    ///
2313    /// let mut source = [85, 85];
2314    /// let _ = ZSTy::try_mut_from_bytes(&mut source[..]); // âš  Compile Error!
2315    /// ```
2316    ///
2317    /// # Examples
2318    ///
2319    /// ```
2320    /// use zerocopy::TryFromBytes;
2321    /// # use zerocopy_derive::*;
2322    ///
2323    /// // The only valid value of this type is the byte `0xC0`
2324    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2325    /// #[repr(u8)]
2326    /// enum C0 { xC0 = 0xC0 }
2327    ///
2328    /// // The only valid value of this type is the bytes `0xC0C0`.
2329    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2330    /// #[repr(C)]
2331    /// struct C0C0(C0, C0);
2332    ///
2333    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2334    /// #[repr(C, packed)]
2335    /// struct Packet {
2336    ///     magic_number: C0C0,
2337    ///     mug_size: u8,
2338    ///     temperature: u8,
2339    ///     marshmallows: [[u8; 2]],
2340    /// }
2341    ///
2342    /// let bytes = &mut [0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5][..];
2343    ///
2344    /// let packet = Packet::try_mut_from_bytes(bytes).unwrap();
2345    ///
2346    /// assert_eq!(packet.mug_size, 240);
2347    /// assert_eq!(packet.temperature, 77);
2348    /// assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);
2349    ///
2350    /// packet.temperature = 111;
2351    ///
2352    /// assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 0, 1, 2, 3, 4, 5]);
2353    ///
2354    /// // These bytes are not valid instance of `Packet`.
2355    /// let bytes = &mut [0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
2356    /// assert!(Packet::try_mut_from_bytes(bytes).is_err());
2357    /// ```
2358    ///
2359    #[doc = codegen_header!("h5", "try_mut_from_bytes")]
2360    ///
2361    /// See [`TryFromBytes::try_ref_from_bytes`](#method.try_ref_from_bytes.codegen).
2362    #[must_use = "the conversion result must be checked"]
2363    #[cfg_attr(zerocopy_inline_always, inline(always))]
2364    #[cfg_attr(not(zerocopy_inline_always), inline)]
2365    fn try_mut_from_bytes(bytes: &mut [u8]) -> Result<&mut Self, TryCastError<&mut [u8], Self>>
2366    where
2367        Self: KnownLayout + IntoBytes,
2368    {
2369        static_assert_dst_is_not_zst!(Self);
2370        match Ptr::from_mut(bytes).try_cast_into_no_leftover::<Self, BecauseExclusive>(None) {
2371            Ok(source) => {
2372                // This call may panic. If that happens, it doesn't cause any soundness
2373                // issues, as we have not generated any invalid state which we need to
2374                // fix before returning.
2375                match source.try_into_safe() {
2376                    Ok(source) => Ok(source.as_mut()),
2377                    Err(e) => Err(e.map_src(|src| src.as_bytes().as_mut()).into()),
2378                }
2379            }
2380            Err(e) => Err(e.map_src(Ptr::as_mut).into()),
2381        }
2382    }
2383
2384    /// Attempts to interpret the prefix of the given `source` as a `&mut
2385    /// Self`.
2386    ///
2387    /// This method computes the [largest possible size of `Self`][valid-size]
2388    /// that can fit in the leading bytes of `source`. If that prefix is a valid
2389    /// instance of `Self`, this method returns a reference to those bytes
2390    /// interpreted as `Self`, and a reference to the remaining bytes. If there
2391    /// are insufficient bytes, or if `source` is not appropriately aligned, or
2392    /// if the bytes are not a valid instance of `Self`, this returns `Err`. If
2393    /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the
2394    /// alignment error][ConvertError::from].
2395    ///
2396    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
2397    ///
2398    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
2399    /// [self-unaligned]: Unaligned
2400    /// [slice-dst]: KnownLayout#dynamically-sized-types
2401    ///
2402    /// # Compile-Time Assertions
2403    ///
2404    /// This method cannot yet be used on unsized types whose dynamically-sized
2405    /// component is zero-sized. Attempting to use this method on such types
2406    /// results in a compile-time assertion error; e.g.:
2407    ///
2408    /// ```compile_fail,E0080
2409    /// use zerocopy::*;
2410    /// # use zerocopy_derive::*;
2411    ///
2412    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2413    /// #[repr(C, packed)]
2414    /// struct ZSTy {
2415    ///     leading_sized: [u8; 2],
2416    ///     trailing_dst: [()],
2417    /// }
2418    ///
2419    /// let mut source = [85, 85];
2420    /// let _ = ZSTy::try_mut_from_prefix(&mut source[..]); // âš  Compile Error!
2421    /// ```
2422    ///
2423    /// # Examples
2424    ///
2425    /// ```
2426    /// use zerocopy::TryFromBytes;
2427    /// # use zerocopy_derive::*;
2428    ///
2429    /// // The only valid value of this type is the byte `0xC0`
2430    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2431    /// #[repr(u8)]
2432    /// enum C0 { xC0 = 0xC0 }
2433    ///
2434    /// // The only valid value of this type is the bytes `0xC0C0`.
2435    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2436    /// #[repr(C)]
2437    /// struct C0C0(C0, C0);
2438    ///
2439    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2440    /// #[repr(C, packed)]
2441    /// struct Packet {
2442    ///     magic_number: C0C0,
2443    ///     mug_size: u8,
2444    ///     temperature: u8,
2445    ///     marshmallows: [[u8; 2]],
2446    /// }
2447    ///
2448    /// // These are more bytes than are needed to encode a `Packet`.
2449    /// let bytes = &mut [0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
2450    ///
2451    /// let (packet, suffix) = Packet::try_mut_from_prefix(bytes).unwrap();
2452    ///
2453    /// assert_eq!(packet.mug_size, 240);
2454    /// assert_eq!(packet.temperature, 77);
2455    /// assert_eq!(packet.marshmallows, [[0, 1], [2, 3], [4, 5]]);
2456    /// assert_eq!(suffix, &[6u8][..]);
2457    ///
2458    /// packet.temperature = 111;
2459    /// suffix[0] = 222;
2460    ///
2461    /// assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 0, 1, 2, 3, 4, 5, 222]);
2462    ///
2463    /// // These bytes are not valid instance of `Packet`.
2464    /// let bytes = &mut [0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
2465    /// assert!(Packet::try_mut_from_prefix(bytes).is_err());
2466    /// ```
2467    ///
2468    #[doc = codegen_header!("h5", "try_mut_from_prefix")]
2469    ///
2470    /// See [`TryFromBytes::try_ref_from_prefix`](#method.try_ref_from_prefix.codegen).
2471    #[must_use = "the conversion result must be checked"]
2472    #[cfg_attr(zerocopy_inline_always, inline(always))]
2473    #[cfg_attr(not(zerocopy_inline_always), inline)]
2474    fn try_mut_from_prefix(
2475        source: &mut [u8],
2476    ) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>>
2477    where
2478        Self: KnownLayout + IntoBytes,
2479    {
2480        static_assert_dst_is_not_zst!(Self);
2481        try_mut_from_prefix_suffix(source, CastType::Prefix, None)
2482    }
2483
2484    /// Attempts to interpret the suffix of the given `source` as a `&mut
2485    /// Self`.
2486    ///
2487    /// This method computes the [largest possible size of `Self`][valid-size]
2488    /// that can fit in the trailing bytes of `source`. If that suffix is a
2489    /// valid instance of `Self`, this method returns a reference to those bytes
2490    /// interpreted as `Self`, and a reference to the preceding bytes. If there
2491    /// are insufficient bytes, or if the suffix of `source` would not be
2492    /// appropriately aligned, or if the suffix is not a valid instance of
2493    /// `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned], you
2494    /// can [infallibly discard the alignment error][ConvertError::from].
2495    ///
2496    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
2497    ///
2498    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
2499    /// [self-unaligned]: Unaligned
2500    /// [slice-dst]: KnownLayout#dynamically-sized-types
2501    ///
2502    /// # Compile-Time Assertions
2503    ///
2504    /// This method cannot yet be used on unsized types whose dynamically-sized
2505    /// component is zero-sized. Attempting to use this method on such types
2506    /// results in a compile-time assertion error; e.g.:
2507    ///
2508    /// ```compile_fail,E0080
2509    /// use zerocopy::*;
2510    /// # use zerocopy_derive::*;
2511    ///
2512    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2513    /// #[repr(C, packed)]
2514    /// struct ZSTy {
2515    ///     leading_sized: u16,
2516    ///     trailing_dst: [()],
2517    /// }
2518    ///
2519    /// let mut source = [85, 85];
2520    /// let _ = ZSTy::try_mut_from_suffix(&mut source[..]); // âš  Compile Error!
2521    /// ```
2522    ///
2523    /// # Examples
2524    ///
2525    /// ```
2526    /// use zerocopy::TryFromBytes;
2527    /// # use zerocopy_derive::*;
2528    ///
2529    /// // The only valid value of this type is the byte `0xC0`
2530    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2531    /// #[repr(u8)]
2532    /// enum C0 { xC0 = 0xC0 }
2533    ///
2534    /// // The only valid value of this type is the bytes `0xC0C0`.
2535    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2536    /// #[repr(C)]
2537    /// struct C0C0(C0, C0);
2538    ///
2539    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2540    /// #[repr(C, packed)]
2541    /// struct Packet {
2542    ///     magic_number: C0C0,
2543    ///     mug_size: u8,
2544    ///     temperature: u8,
2545    ///     marshmallows: [[u8; 2]],
2546    /// }
2547    ///
2548    /// // These are more bytes than are needed to encode a `Packet`.
2549    /// let bytes = &mut [0, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
2550    ///
2551    /// let (prefix, packet) = Packet::try_mut_from_suffix(bytes).unwrap();
2552    ///
2553    /// assert_eq!(packet.mug_size, 240);
2554    /// assert_eq!(packet.temperature, 77);
2555    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2556    /// assert_eq!(prefix, &[0u8][..]);
2557    ///
2558    /// prefix[0] = 111;
2559    /// packet.temperature = 222;
2560    ///
2561    /// assert_eq!(bytes, [111, 0xC0, 0xC0, 240, 222, 2, 3, 4, 5, 6, 7]);
2562    ///
2563    /// // These bytes are not valid instance of `Packet`.
2564    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0x10][..];
2565    /// assert!(Packet::try_mut_from_suffix(bytes).is_err());
2566    /// ```
2567    ///
2568    #[doc = codegen_header!("h5", "try_mut_from_suffix")]
2569    ///
2570    /// See [`TryFromBytes::try_ref_from_suffix`](#method.try_ref_from_suffix.codegen).
2571    #[must_use = "the conversion result must be checked"]
2572    #[cfg_attr(zerocopy_inline_always, inline(always))]
2573    #[cfg_attr(not(zerocopy_inline_always), inline)]
2574    fn try_mut_from_suffix(
2575        source: &mut [u8],
2576    ) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>>
2577    where
2578        Self: KnownLayout + IntoBytes,
2579    {
2580        static_assert_dst_is_not_zst!(Self);
2581        try_mut_from_prefix_suffix(source, CastType::Suffix, None).map(swap)
2582    }
2583
2584    /// Attempts to interpret the given `source` as a `&Self` with a DST length
2585    /// equal to `count`.
2586    ///
2587    /// This method attempts to return a reference to `source` interpreted as a
2588    /// `Self` with `count` trailing elements. If the length of `source` is not
2589    /// equal to the size of `Self` with `count` elements, if `source` is not
2590    /// appropriately aligned, or if `source` does not contain a valid instance
2591    /// of `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned],
2592    /// you can [infallibly discard the alignment error][ConvertError::from].
2593    ///
2594    /// [self-unaligned]: Unaligned
2595    /// [slice-dst]: KnownLayout#dynamically-sized-types
2596    ///
2597    /// # Examples
2598    ///
2599    /// ```
2600    /// # #![allow(non_camel_case_types)] // For C0::xC0
2601    /// use zerocopy::TryFromBytes;
2602    /// # use zerocopy_derive::*;
2603    ///
2604    /// // The only valid value of this type is the byte `0xC0`
2605    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2606    /// #[repr(u8)]
2607    /// enum C0 { xC0 = 0xC0 }
2608    ///
2609    /// // The only valid value of this type is the bytes `0xC0C0`.
2610    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2611    /// #[repr(C)]
2612    /// struct C0C0(C0, C0);
2613    ///
2614    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2615    /// #[repr(C)]
2616    /// struct Packet {
2617    ///     magic_number: C0C0,
2618    ///     mug_size: u8,
2619    ///     temperature: u8,
2620    ///     marshmallows: [[u8; 2]],
2621    /// }
2622    ///
2623    /// let bytes = &[0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
2624    ///
2625    /// let packet = Packet::try_ref_from_bytes_with_elems(bytes, 3).unwrap();
2626    ///
2627    /// assert_eq!(packet.mug_size, 240);
2628    /// assert_eq!(packet.temperature, 77);
2629    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2630    ///
2631    /// // These bytes are not valid instance of `Packet`.
2632    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0xC0][..];
2633    /// assert!(Packet::try_ref_from_bytes_with_elems(bytes, 3).is_err());
2634    /// ```
2635    ///
2636    /// Since an explicit `count` is provided, this method supports types with
2637    /// zero-sized trailing slice elements. Methods such as [`try_ref_from_bytes`]
2638    /// which do not take an explicit count do not support such types.
2639    ///
2640    /// ```
2641    /// use core::num::NonZeroU16;
2642    /// use zerocopy::*;
2643    /// # use zerocopy_derive::*;
2644    ///
2645    /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2646    /// #[repr(C)]
2647    /// struct ZSTy {
2648    ///     leading_sized: NonZeroU16,
2649    ///     trailing_dst: [()],
2650    /// }
2651    ///
2652    /// let src = 0xCAFEu16.as_bytes();
2653    /// let zsty = ZSTy::try_ref_from_bytes_with_elems(src, 42).unwrap();
2654    /// assert_eq!(zsty.trailing_dst.len(), 42);
2655    /// ```
2656    ///
2657    /// [`try_ref_from_bytes`]: TryFromBytes::try_ref_from_bytes
2658    ///
2659    #[doc = codegen_section!(
2660        header = "h5",
2661        bench = "try_ref_from_bytes_with_elems",
2662        format = "coco",
2663        arity = 2,
2664        [
2665            open
2666            @index 1
2667            @title "Unsized"
2668            @variant "dynamic_size"
2669        ],
2670        [
2671            @index 2
2672            @title "Dynamically Padded"
2673            @variant "dynamic_padding"
2674        ]
2675    )]
2676    #[must_use = "the conversion result must be checked"]
2677    #[cfg_attr(zerocopy_inline_always, inline(always))]
2678    #[cfg_attr(not(zerocopy_inline_always), inline)]
2679    fn try_ref_from_bytes_with_elems(
2680        source: &[u8],
2681        count: usize,
2682    ) -> Result<&Self, TryCastError<&[u8], Self>>
2683    where
2684        Self: KnownLayout<PointerMetadata = usize> + Immutable,
2685    {
2686        match Ptr::from_ref(source).try_cast_into_no_leftover::<Self, BecauseImmutable>(Some(count))
2687        {
2688            Ok(source) => {
2689                // This call may panic. If that happens, it doesn't cause any soundness
2690                // issues, as we have not generated any invalid state which we need to
2691                // fix before returning.
2692                match source.try_into_safe() {
2693                    Ok(source) => Ok(source.as_ref()),
2694                    Err(e) => {
2695                        Err(e.map_src(|src| src.as_bytes::<BecauseImmutable>().as_ref()).into())
2696                    }
2697                }
2698            }
2699            Err(e) => Err(e.map_src(Ptr::as_ref).into()),
2700        }
2701    }
2702
2703    /// Attempts to interpret the prefix of the given `source` as a `&Self` with
2704    /// a DST length equal to `count`.
2705    ///
2706    /// This method attempts to return a reference to the prefix of `source`
2707    /// interpreted as a `Self` with `count` trailing elements, and a reference
2708    /// to the remaining bytes. If the length of `source` is less than the size
2709    /// of `Self` with `count` elements, if `source` is not appropriately
2710    /// aligned, or if the prefix of `source` does not contain a valid instance
2711    /// of `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned],
2712    /// you can [infallibly discard the alignment error][ConvertError::from].
2713    ///
2714    /// [self-unaligned]: Unaligned
2715    /// [slice-dst]: KnownLayout#dynamically-sized-types
2716    ///
2717    /// # Examples
2718    ///
2719    /// ```
2720    /// # #![allow(non_camel_case_types)] // For C0::xC0
2721    /// use zerocopy::TryFromBytes;
2722    /// # use zerocopy_derive::*;
2723    ///
2724    /// // The only valid value of this type is the byte `0xC0`
2725    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2726    /// #[repr(u8)]
2727    /// enum C0 { xC0 = 0xC0 }
2728    ///
2729    /// // The only valid value of this type is the bytes `0xC0C0`.
2730    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2731    /// #[repr(C)]
2732    /// struct C0C0(C0, C0);
2733    ///
2734    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2735    /// #[repr(C)]
2736    /// struct Packet {
2737    ///     magic_number: C0C0,
2738    ///     mug_size: u8,
2739    ///     temperature: u8,
2740    ///     marshmallows: [[u8; 2]],
2741    /// }
2742    ///
2743    /// let bytes = &[0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7, 8][..];
2744    ///
2745    /// let (packet, suffix) = Packet::try_ref_from_prefix_with_elems(bytes, 3).unwrap();
2746    ///
2747    /// assert_eq!(packet.mug_size, 240);
2748    /// assert_eq!(packet.temperature, 77);
2749    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2750    /// assert_eq!(suffix, &[8u8][..]);
2751    ///
2752    /// // These bytes are not valid instance of `Packet`.
2753    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
2754    /// assert!(Packet::try_ref_from_prefix_with_elems(bytes, 3).is_err());
2755    /// ```
2756    ///
2757    /// Since an explicit `count` is provided, this method supports types with
2758    /// zero-sized trailing slice elements. Methods such as [`try_ref_from_prefix`]
2759    /// which do not take an explicit count do not support such types.
2760    ///
2761    /// ```
2762    /// use core::num::NonZeroU16;
2763    /// use zerocopy::*;
2764    /// # use zerocopy_derive::*;
2765    ///
2766    /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2767    /// #[repr(C)]
2768    /// struct ZSTy {
2769    ///     leading_sized: NonZeroU16,
2770    ///     trailing_dst: [()],
2771    /// }
2772    ///
2773    /// let src = 0xCAFEu16.as_bytes();
2774    /// let (zsty, _) = ZSTy::try_ref_from_prefix_with_elems(src, 42).unwrap();
2775    /// assert_eq!(zsty.trailing_dst.len(), 42);
2776    /// ```
2777    ///
2778    /// [`try_ref_from_prefix`]: TryFromBytes::try_ref_from_prefix
2779    ///
2780    #[doc = codegen_section!(
2781        header = "h5",
2782        bench = "try_ref_from_prefix_with_elems",
2783        format = "coco",
2784        arity = 2,
2785        [
2786            open
2787            @index 1
2788            @title "Unsized"
2789            @variant "dynamic_size"
2790        ],
2791        [
2792            @index 2
2793            @title "Dynamically Padded"
2794            @variant "dynamic_padding"
2795        ]
2796    )]
2797    #[must_use = "the conversion result must be checked"]
2798    #[cfg_attr(zerocopy_inline_always, inline(always))]
2799    #[cfg_attr(not(zerocopy_inline_always), inline)]
2800    fn try_ref_from_prefix_with_elems(
2801        source: &[u8],
2802        count: usize,
2803    ) -> Result<(&Self, &[u8]), TryCastError<&[u8], Self>>
2804    where
2805        Self: KnownLayout<PointerMetadata = usize> + Immutable,
2806    {
2807        try_ref_from_prefix_suffix(source, CastType::Prefix, Some(count))
2808    }
2809
2810    /// Attempts to interpret the suffix of the given `source` as a `&Self` with
2811    /// a DST length equal to `count`.
2812    ///
2813    /// This method attempts to return a reference to the suffix of `source`
2814    /// interpreted as a `Self` with `count` trailing elements, and a reference
2815    /// to the preceding bytes. If the length of `source` is less than the size
2816    /// of `Self` with `count` elements, if the suffix of `source` is not
2817    /// appropriately aligned, or if the suffix of `source` does not contain a
2818    /// valid instance of `Self`, this returns `Err`. If [`Self:
2819    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
2820    /// error][ConvertError::from].
2821    ///
2822    /// [self-unaligned]: Unaligned
2823    /// [slice-dst]: KnownLayout#dynamically-sized-types
2824    ///
2825    /// # Examples
2826    ///
2827    /// ```
2828    /// # #![allow(non_camel_case_types)] // For C0::xC0
2829    /// use zerocopy::TryFromBytes;
2830    /// # use zerocopy_derive::*;
2831    ///
2832    /// // The only valid value of this type is the byte `0xC0`
2833    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2834    /// #[repr(u8)]
2835    /// enum C0 { xC0 = 0xC0 }
2836    ///
2837    /// // The only valid value of this type is the bytes `0xC0C0`.
2838    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2839    /// #[repr(C)]
2840    /// struct C0C0(C0, C0);
2841    ///
2842    /// #[derive(TryFromBytes, KnownLayout, Immutable)]
2843    /// #[repr(C)]
2844    /// struct Packet {
2845    ///     magic_number: C0C0,
2846    ///     mug_size: u8,
2847    ///     temperature: u8,
2848    ///     marshmallows: [[u8; 2]],
2849    /// }
2850    ///
2851    /// let bytes = &[123, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
2852    ///
2853    /// let (prefix, packet) = Packet::try_ref_from_suffix_with_elems(bytes, 3).unwrap();
2854    ///
2855    /// assert_eq!(packet.mug_size, 240);
2856    /// assert_eq!(packet.temperature, 77);
2857    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2858    /// assert_eq!(prefix, &[123u8][..]);
2859    ///
2860    /// // These bytes are not valid instance of `Packet`.
2861    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
2862    /// assert!(Packet::try_ref_from_suffix_with_elems(bytes, 3).is_err());
2863    /// ```
2864    ///
2865    /// Since an explicit `count` is provided, this method supports types with
2866    /// zero-sized trailing slice elements. Methods such as [`try_ref_from_prefix`]
2867    /// which do not take an explicit count do not support such types.
2868    ///
2869    /// ```
2870    /// use core::num::NonZeroU16;
2871    /// use zerocopy::*;
2872    /// # use zerocopy_derive::*;
2873    ///
2874    /// #[derive(TryFromBytes, Immutable, KnownLayout)]
2875    /// #[repr(C)]
2876    /// struct ZSTy {
2877    ///     leading_sized: NonZeroU16,
2878    ///     trailing_dst: [()],
2879    /// }
2880    ///
2881    /// let src = 0xCAFEu16.as_bytes();
2882    /// let (_, zsty) = ZSTy::try_ref_from_suffix_with_elems(src, 42).unwrap();
2883    /// assert_eq!(zsty.trailing_dst.len(), 42);
2884    /// ```
2885    ///
2886    /// [`try_ref_from_prefix`]: TryFromBytes::try_ref_from_prefix
2887    ///
2888    #[doc = codegen_section!(
2889        header = "h5",
2890        bench = "try_ref_from_suffix_with_elems",
2891        format = "coco",
2892        arity = 2,
2893        [
2894            open
2895            @index 1
2896            @title "Unsized"
2897            @variant "dynamic_size"
2898        ],
2899        [
2900            @index 2
2901            @title "Dynamically Padded"
2902            @variant "dynamic_padding"
2903        ]
2904    )]
2905    #[must_use = "the conversion result must be checked"]
2906    #[cfg_attr(zerocopy_inline_always, inline(always))]
2907    #[cfg_attr(not(zerocopy_inline_always), inline)]
2908    fn try_ref_from_suffix_with_elems(
2909        source: &[u8],
2910        count: usize,
2911    ) -> Result<(&[u8], &Self), TryCastError<&[u8], Self>>
2912    where
2913        Self: KnownLayout<PointerMetadata = usize> + Immutable,
2914    {
2915        try_ref_from_prefix_suffix(source, CastType::Suffix, Some(count)).map(swap)
2916    }
2917
2918    /// Attempts to interpret the given `source` as a `&mut Self` with a DST
2919    /// length equal to `count`.
2920    ///
2921    /// This method attempts to return a reference to `source` interpreted as a
2922    /// `Self` with `count` trailing elements. If the length of `source` is not
2923    /// equal to the size of `Self` with `count` elements, if `source` is not
2924    /// appropriately aligned, or if `source` does not contain a valid instance
2925    /// of `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned],
2926    /// you can [infallibly discard the alignment error][ConvertError::from].
2927    ///
2928    /// [self-unaligned]: Unaligned
2929    /// [slice-dst]: KnownLayout#dynamically-sized-types
2930    ///
2931    /// # Examples
2932    ///
2933    /// ```
2934    /// # #![allow(non_camel_case_types)] // For C0::xC0
2935    /// use zerocopy::TryFromBytes;
2936    /// # use zerocopy_derive::*;
2937    ///
2938    /// // The only valid value of this type is the byte `0xC0`
2939    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2940    /// #[repr(u8)]
2941    /// enum C0 { xC0 = 0xC0 }
2942    ///
2943    /// // The only valid value of this type is the bytes `0xC0C0`.
2944    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2945    /// #[repr(C)]
2946    /// struct C0C0(C0, C0);
2947    ///
2948    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2949    /// #[repr(C, packed)]
2950    /// struct Packet {
2951    ///     magic_number: C0C0,
2952    ///     mug_size: u8,
2953    ///     temperature: u8,
2954    ///     marshmallows: [[u8; 2]],
2955    /// }
2956    ///
2957    /// let bytes = &mut [0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
2958    ///
2959    /// let packet = Packet::try_mut_from_bytes_with_elems(bytes, 3).unwrap();
2960    ///
2961    /// assert_eq!(packet.mug_size, 240);
2962    /// assert_eq!(packet.temperature, 77);
2963    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
2964    ///
2965    /// packet.temperature = 111;
2966    ///
2967    /// assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 2, 3, 4, 5, 6, 7]);
2968    ///
2969    /// // These bytes are not valid instance of `Packet`.
2970    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 77, 240, 0xC0, 0xC0][..];
2971    /// assert!(Packet::try_mut_from_bytes_with_elems(bytes, 3).is_err());
2972    /// ```
2973    ///
2974    /// Since an explicit `count` is provided, this method supports types with
2975    /// zero-sized trailing slice elements. Methods such as [`try_mut_from_bytes`]
2976    /// which do not take an explicit count do not support such types.
2977    ///
2978    /// ```
2979    /// use core::num::NonZeroU16;
2980    /// use zerocopy::*;
2981    /// # use zerocopy_derive::*;
2982    ///
2983    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
2984    /// #[repr(C, packed)]
2985    /// struct ZSTy {
2986    ///     leading_sized: NonZeroU16,
2987    ///     trailing_dst: [()],
2988    /// }
2989    ///
2990    /// let mut src = 0xCAFEu16;
2991    /// let src = src.as_mut_bytes();
2992    /// let zsty = ZSTy::try_mut_from_bytes_with_elems(src, 42).unwrap();
2993    /// assert_eq!(zsty.trailing_dst.len(), 42);
2994    /// ```
2995    ///
2996    /// [`try_mut_from_bytes`]: TryFromBytes::try_mut_from_bytes
2997    ///
2998    #[doc = codegen_header!("h5", "try_mut_from_bytes_with_elems")]
2999    ///
3000    /// See [`TryFromBytes::try_ref_from_bytes_with_elems`](#method.try_ref_from_bytes_with_elems.codegen).
3001    #[must_use = "the conversion result must be checked"]
3002    #[cfg_attr(zerocopy_inline_always, inline(always))]
3003    #[cfg_attr(not(zerocopy_inline_always), inline)]
3004    fn try_mut_from_bytes_with_elems(
3005        source: &mut [u8],
3006        count: usize,
3007    ) -> Result<&mut Self, TryCastError<&mut [u8], Self>>
3008    where
3009        Self: KnownLayout<PointerMetadata = usize> + IntoBytes,
3010    {
3011        match Ptr::from_mut(source).try_cast_into_no_leftover::<Self, BecauseExclusive>(Some(count))
3012        {
3013            Ok(source) => {
3014                // This call may panic. If that happens, it doesn't cause any soundness
3015                // issues, as we have not generated any invalid state which we need to
3016                // fix before returning.
3017                match source.try_into_safe() {
3018                    Ok(source) => Ok(source.as_mut()),
3019                    Err(e) => Err(e.map_src(|src| src.as_bytes().as_mut()).into()),
3020                }
3021            }
3022            Err(e) => Err(e.map_src(Ptr::as_mut).into()),
3023        }
3024    }
3025
3026    /// Attempts to interpret the prefix of the given `source` as a `&mut Self`
3027    /// with a DST length equal to `count`.
3028    ///
3029    /// This method attempts to return a reference to the prefix of `source`
3030    /// interpreted as a `Self` with `count` trailing elements, and a reference
3031    /// to the remaining bytes. If the length of `source` is less than the size
3032    /// of `Self` with `count` elements, if `source` is not appropriately
3033    /// aligned, or if the prefix of `source` does not contain a valid instance
3034    /// of `Self`, this returns `Err`. If [`Self: Unaligned`][self-unaligned],
3035    /// you can [infallibly discard the alignment error][ConvertError::from].
3036    ///
3037    /// [self-unaligned]: Unaligned
3038    /// [slice-dst]: KnownLayout#dynamically-sized-types
3039    ///
3040    /// # Examples
3041    ///
3042    /// ```
3043    /// # #![allow(non_camel_case_types)] // For C0::xC0
3044    /// use zerocopy::TryFromBytes;
3045    /// # use zerocopy_derive::*;
3046    ///
3047    /// // The only valid value of this type is the byte `0xC0`
3048    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3049    /// #[repr(u8)]
3050    /// enum C0 { xC0 = 0xC0 }
3051    ///
3052    /// // The only valid value of this type is the bytes `0xC0C0`.
3053    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3054    /// #[repr(C)]
3055    /// struct C0C0(C0, C0);
3056    ///
3057    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3058    /// #[repr(C, packed)]
3059    /// struct Packet {
3060    ///     magic_number: C0C0,
3061    ///     mug_size: u8,
3062    ///     temperature: u8,
3063    ///     marshmallows: [[u8; 2]],
3064    /// }
3065    ///
3066    /// let bytes = &mut [0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7, 8][..];
3067    ///
3068    /// let (packet, suffix) = Packet::try_mut_from_prefix_with_elems(bytes, 3).unwrap();
3069    ///
3070    /// assert_eq!(packet.mug_size, 240);
3071    /// assert_eq!(packet.temperature, 77);
3072    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
3073    /// assert_eq!(suffix, &[8u8][..]);
3074    ///
3075    /// packet.temperature = 111;
3076    /// suffix[0] = 222;
3077    ///
3078    /// assert_eq!(bytes, [0xC0, 0xC0, 240, 111, 2, 3, 4, 5, 6, 7, 222]);
3079    ///
3080    /// // These bytes are not valid instance of `Packet`.
3081    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
3082    /// assert!(Packet::try_mut_from_prefix_with_elems(bytes, 3).is_err());
3083    /// ```
3084    ///
3085    /// Since an explicit `count` is provided, this method supports types with
3086    /// zero-sized trailing slice elements. Methods such as [`try_mut_from_prefix`]
3087    /// which do not take an explicit count do not support such types.
3088    ///
3089    /// ```
3090    /// use core::num::NonZeroU16;
3091    /// use zerocopy::*;
3092    /// # use zerocopy_derive::*;
3093    ///
3094    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3095    /// #[repr(C, packed)]
3096    /// struct ZSTy {
3097    ///     leading_sized: NonZeroU16,
3098    ///     trailing_dst: [()],
3099    /// }
3100    ///
3101    /// let mut src = 0xCAFEu16;
3102    /// let src = src.as_mut_bytes();
3103    /// let (zsty, _) = ZSTy::try_mut_from_prefix_with_elems(src, 42).unwrap();
3104    /// assert_eq!(zsty.trailing_dst.len(), 42);
3105    /// ```
3106    ///
3107    /// [`try_mut_from_prefix`]: TryFromBytes::try_mut_from_prefix
3108    ///
3109    #[doc = codegen_header!("h5", "try_mut_from_prefix_with_elems")]
3110    ///
3111    /// See [`TryFromBytes::try_ref_from_prefix_with_elems`](#method.try_ref_from_prefix_with_elems.codegen).
3112    #[must_use = "the conversion result must be checked"]
3113    #[cfg_attr(zerocopy_inline_always, inline(always))]
3114    #[cfg_attr(not(zerocopy_inline_always), inline)]
3115    fn try_mut_from_prefix_with_elems(
3116        source: &mut [u8],
3117        count: usize,
3118    ) -> Result<(&mut Self, &mut [u8]), TryCastError<&mut [u8], Self>>
3119    where
3120        Self: KnownLayout<PointerMetadata = usize> + IntoBytes,
3121    {
3122        try_mut_from_prefix_suffix(source, CastType::Prefix, Some(count))
3123    }
3124
3125    /// Attempts to interpret the suffix of the given `source` as a `&mut Self`
3126    /// with a DST length equal to `count`.
3127    ///
3128    /// This method attempts to return a reference to the suffix of `source`
3129    /// interpreted as a `Self` with `count` trailing elements, and a reference
3130    /// to the preceding bytes. If the length of `source` is less than the size
3131    /// of `Self` with `count` elements, if the suffix of `source` is not
3132    /// appropriately aligned, or if the suffix of `source` does not contain a
3133    /// valid instance of `Self`, this returns `Err`. If [`Self:
3134    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
3135    /// error][ConvertError::from].
3136    ///
3137    /// [self-unaligned]: Unaligned
3138    /// [slice-dst]: KnownLayout#dynamically-sized-types
3139    ///
3140    /// # Examples
3141    ///
3142    /// ```
3143    /// # #![allow(non_camel_case_types)] // For C0::xC0
3144    /// use zerocopy::TryFromBytes;
3145    /// # use zerocopy_derive::*;
3146    ///
3147    /// // The only valid value of this type is the byte `0xC0`
3148    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3149    /// #[repr(u8)]
3150    /// enum C0 { xC0 = 0xC0 }
3151    ///
3152    /// // The only valid value of this type is the bytes `0xC0C0`.
3153    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3154    /// #[repr(C)]
3155    /// struct C0C0(C0, C0);
3156    ///
3157    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3158    /// #[repr(C, packed)]
3159    /// struct Packet {
3160    ///     magic_number: C0C0,
3161    ///     mug_size: u8,
3162    ///     temperature: u8,
3163    ///     marshmallows: [[u8; 2]],
3164    /// }
3165    ///
3166    /// let bytes = &mut [123, 0xC0, 0xC0, 240, 77, 2, 3, 4, 5, 6, 7][..];
3167    ///
3168    /// let (prefix, packet) = Packet::try_mut_from_suffix_with_elems(bytes, 3).unwrap();
3169    ///
3170    /// assert_eq!(packet.mug_size, 240);
3171    /// assert_eq!(packet.temperature, 77);
3172    /// assert_eq!(packet.marshmallows, [[2, 3], [4, 5], [6, 7]]);
3173    /// assert_eq!(prefix, &[123u8][..]);
3174    ///
3175    /// prefix[0] = 111;
3176    /// packet.temperature = 222;
3177    ///
3178    /// assert_eq!(bytes, [111, 0xC0, 0xC0, 240, 222, 2, 3, 4, 5, 6, 7]);
3179    ///
3180    /// // These bytes are not valid instance of `Packet`.
3181    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 77, 240, 0xC0, 0xC0][..];
3182    /// assert!(Packet::try_mut_from_suffix_with_elems(bytes, 3).is_err());
3183    /// ```
3184    ///
3185    /// Since an explicit `count` is provided, this method supports types with
3186    /// zero-sized trailing slice elements. Methods such as [`try_mut_from_prefix`]
3187    /// which do not take an explicit count do not support such types.
3188    ///
3189    /// ```
3190    /// use core::num::NonZeroU16;
3191    /// use zerocopy::*;
3192    /// # use zerocopy_derive::*;
3193    ///
3194    /// #[derive(TryFromBytes, IntoBytes, KnownLayout)]
3195    /// #[repr(C, packed)]
3196    /// struct ZSTy {
3197    ///     leading_sized: NonZeroU16,
3198    ///     trailing_dst: [()],
3199    /// }
3200    ///
3201    /// let mut src = 0xCAFEu16;
3202    /// let src = src.as_mut_bytes();
3203    /// let (_, zsty) = ZSTy::try_mut_from_suffix_with_elems(src, 42).unwrap();
3204    /// assert_eq!(zsty.trailing_dst.len(), 42);
3205    /// ```
3206    ///
3207    /// [`try_mut_from_prefix`]: TryFromBytes::try_mut_from_prefix
3208    ///
3209    #[doc = codegen_header!("h5", "try_mut_from_suffix_with_elems")]
3210    ///
3211    /// See [`TryFromBytes::try_ref_from_suffix_with_elems`](#method.try_ref_from_suffix_with_elems.codegen).
3212    #[must_use = "the conversion result must be checked"]
3213    #[cfg_attr(zerocopy_inline_always, inline(always))]
3214    #[cfg_attr(not(zerocopy_inline_always), inline)]
3215    fn try_mut_from_suffix_with_elems(
3216        source: &mut [u8],
3217        count: usize,
3218    ) -> Result<(&mut [u8], &mut Self), TryCastError<&mut [u8], Self>>
3219    where
3220        Self: KnownLayout<PointerMetadata = usize> + IntoBytes,
3221    {
3222        try_mut_from_prefix_suffix(source, CastType::Suffix, Some(count)).map(swap)
3223    }
3224
3225    /// Attempts to read the given `source` as a `Self`.
3226    ///
3227    /// If `source.len() != size_of::<Self>()` or the bytes are not a valid
3228    /// instance of `Self`, this returns `Err`.
3229    ///
3230    /// # Examples
3231    ///
3232    /// ```
3233    /// use zerocopy::TryFromBytes;
3234    /// # use zerocopy_derive::*;
3235    ///
3236    /// // The only valid value of this type is the byte `0xC0`
3237    /// #[derive(TryFromBytes)]
3238    /// #[repr(u8)]
3239    /// enum C0 { xC0 = 0xC0 }
3240    ///
3241    /// // The only valid value of this type is the bytes `0xC0C0`.
3242    /// #[derive(TryFromBytes)]
3243    /// #[repr(C)]
3244    /// struct C0C0(C0, C0);
3245    ///
3246    /// #[derive(TryFromBytes)]
3247    /// #[repr(C)]
3248    /// struct Packet {
3249    ///     magic_number: C0C0,
3250    ///     mug_size: u8,
3251    ///     temperature: u8,
3252    /// }
3253    ///
3254    /// let bytes = &[0xC0, 0xC0, 240, 77][..];
3255    ///
3256    /// let packet = Packet::try_read_from_bytes(bytes).unwrap();
3257    ///
3258    /// assert_eq!(packet.mug_size, 240);
3259    /// assert_eq!(packet.temperature, 77);
3260    ///
3261    /// // These bytes are not valid instance of `Packet`.
3262    /// let bytes = &mut [0x10, 0xC0, 240, 77][..];
3263    /// assert!(Packet::try_read_from_bytes(bytes).is_err());
3264    /// ```
3265    ///
3266    /// # Performance Considerations
3267    ///
3268    /// In this version of zerocopy, this method reads the `source` into a
3269    /// well-aligned stack allocation and *then* validates that the allocation
3270    /// is a valid `Self`. This ensures that validation can be performed using
3271    /// aligned reads (which carry a performance advantage over unaligned reads
3272    /// on many platforms) at the cost of an unconditional copy.
3273    ///
3274    #[doc = codegen_section!(
3275        header = "h5",
3276        bench = "try_read_from_bytes",
3277        format = "coco_static_size",
3278    )]
3279    #[must_use = "the conversion result must be checked"]
3280    #[cfg_attr(zerocopy_inline_always, inline(always))]
3281    #[cfg_attr(not(zerocopy_inline_always), inline)]
3282    fn try_read_from_bytes(source: &[u8]) -> Result<Self, TryReadError<&[u8], Self>>
3283    where
3284        Self: Sized,
3285    {
3286        try_read_from(source)
3287    }
3288
3289    /// Attempts to read a `Self` from the prefix of the given `source`.
3290    ///
3291    /// This attempts to read a `Self` from the first `size_of::<Self>()` bytes
3292    /// of `source`, returning that `Self` and any remaining bytes. If
3293    /// `source.len() < size_of::<Self>()` or the bytes are not a valid instance
3294    /// of `Self`, it returns `Err`.
3295    ///
3296    /// # Examples
3297    ///
3298    /// ```
3299    /// use zerocopy::TryFromBytes;
3300    /// # use zerocopy_derive::*;
3301    ///
3302    /// // The only valid value of this type is the byte `0xC0`
3303    /// #[derive(TryFromBytes)]
3304    /// #[repr(u8)]
3305    /// enum C0 { xC0 = 0xC0 }
3306    ///
3307    /// // The only valid value of this type is the bytes `0xC0C0`.
3308    /// #[derive(TryFromBytes)]
3309    /// #[repr(C)]
3310    /// struct C0C0(C0, C0);
3311    ///
3312    /// #[derive(TryFromBytes)]
3313    /// #[repr(C)]
3314    /// struct Packet {
3315    ///     magic_number: C0C0,
3316    ///     mug_size: u8,
3317    ///     temperature: u8,
3318    /// }
3319    ///
3320    /// // These are more bytes than are needed to encode a `Packet`.
3321    /// let bytes = &[0xC0, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
3322    ///
3323    /// let (packet, suffix) = Packet::try_read_from_prefix(bytes).unwrap();
3324    ///
3325    /// assert_eq!(packet.mug_size, 240);
3326    /// assert_eq!(packet.temperature, 77);
3327    /// assert_eq!(suffix, &[0u8, 1, 2, 3, 4, 5, 6][..]);
3328    ///
3329    /// // These bytes are not valid instance of `Packet`.
3330    /// let bytes = &[0x10, 0xC0, 240, 77, 0, 1, 2, 3, 4, 5, 6][..];
3331    /// assert!(Packet::try_read_from_prefix(bytes).is_err());
3332    /// ```
3333    ///
3334    /// # Performance Considerations
3335    ///
3336    /// In this version of zerocopy, this method reads the `source` into a
3337    /// well-aligned stack allocation and *then* validates that the allocation
3338    /// is a valid `Self`. This ensures that validation can be performed using
3339    /// aligned reads (which carry a performance advantage over unaligned reads
3340    /// on many platforms) at the cost of an unconditional copy.
3341    ///
3342    #[doc = codegen_section!(
3343        header = "h5",
3344        bench = "try_read_from_prefix",
3345        format = "coco_static_size",
3346    )]
3347    #[must_use = "the conversion result must be checked"]
3348    #[cfg_attr(zerocopy_inline_always, inline(always))]
3349    #[cfg_attr(not(zerocopy_inline_always), inline)]
3350    fn try_read_from_prefix(source: &[u8]) -> Result<(Self, &[u8]), TryReadError<&[u8], Self>>
3351    where
3352        Self: Sized,
3353    {
3354        let (prefix, suffix) = match SplitAt::split_at(source, mem::size_of::<Self>()) {
3355            Some(split) => split.via_immutable(),
3356            None => return Err(SizeError::new(source).into()),
3357        };
3358        match try_read_from(prefix) {
3359            Ok(slf) => Ok((slf, suffix)),
3360            Err(e) => Err(e.map_src(
3361                #[inline(always)]
3362                |_| source,
3363            )),
3364        }
3365    }
3366
3367    /// Attempts to read a `Self` from the suffix of the given `source`.
3368    ///
3369    /// This attempts to read a `Self` from the last `size_of::<Self>()` bytes
3370    /// of `source`, returning that `Self` and any preceding bytes. If
3371    /// `source.len() < size_of::<Self>()` or the bytes are not a valid instance
3372    /// of `Self`, it returns `Err`.
3373    ///
3374    /// # Examples
3375    ///
3376    /// ```
3377    /// # #![allow(non_camel_case_types)] // For C0::xC0
3378    /// use zerocopy::TryFromBytes;
3379    /// # use zerocopy_derive::*;
3380    ///
3381    /// // The only valid value of this type is the byte `0xC0`
3382    /// #[derive(TryFromBytes)]
3383    /// #[repr(u8)]
3384    /// enum C0 { xC0 = 0xC0 }
3385    ///
3386    /// // The only valid value of this type is the bytes `0xC0C0`.
3387    /// #[derive(TryFromBytes)]
3388    /// #[repr(C)]
3389    /// struct C0C0(C0, C0);
3390    ///
3391    /// #[derive(TryFromBytes)]
3392    /// #[repr(C)]
3393    /// struct Packet {
3394    ///     magic_number: C0C0,
3395    ///     mug_size: u8,
3396    ///     temperature: u8,
3397    /// }
3398    ///
3399    /// // These are more bytes than are needed to encode a `Packet`.
3400    /// let bytes = &[0, 1, 2, 3, 4, 5, 0xC0, 0xC0, 240, 77][..];
3401    ///
3402    /// let (prefix, packet) = Packet::try_read_from_suffix(bytes).unwrap();
3403    ///
3404    /// assert_eq!(packet.mug_size, 240);
3405    /// assert_eq!(packet.temperature, 77);
3406    /// assert_eq!(prefix, &[0u8, 1, 2, 3, 4, 5][..]);
3407    ///
3408    /// // These bytes are not valid instance of `Packet`.
3409    /// let bytes = &[0, 1, 2, 3, 4, 5, 0x10, 0xC0, 240, 77][..];
3410    /// assert!(Packet::try_read_from_suffix(bytes).is_err());
3411    /// ```
3412    ///
3413    /// # Performance Considerations
3414    ///
3415    /// In this version of zerocopy, this method reads the `source` into a
3416    /// well-aligned stack allocation and *then* validates that the allocation
3417    /// is a valid `Self`. This ensures that validation can be performed using
3418    /// aligned reads (which carry a performance advantage over unaligned reads
3419    /// on many platforms) at the cost of an unconditional copy.
3420    ///
3421    #[doc = codegen_section!(
3422        header = "h5",
3423        bench = "try_read_from_suffix",
3424        format = "coco_static_size",
3425    )]
3426    #[must_use = "the conversion result must be checked"]
3427    #[cfg_attr(zerocopy_inline_always, inline(always))]
3428    #[cfg_attr(not(zerocopy_inline_always), inline)]
3429    fn try_read_from_suffix(source: &[u8]) -> Result<(&[u8], Self), TryReadError<&[u8], Self>>
3430    where
3431        Self: Sized,
3432    {
3433        let split_at = match source.len().checked_sub(mem::size_of::<Self>()) {
3434            Some(split_at) => split_at,
3435            None => return Err(SizeError::new(source).into()),
3436        };
3437        // SAFETY: `checked_sub` returned the difference without overflow [1],
3438        // so `split_at = source.len() - size_of::<Self>() <= source.len()`.
3439        // This satisfies `SplitAt::split_at_unchecked`'s precondition.
3440        //
3441        // [1] Per https://doc.rust-lang.org/1.56.0/std/primitive.usize.html#method.checked_sub:
3442        //
3443        //   Checked integer subtraction. Computes `self - rhs`, returning
3444        //   `None` if overflow occurred.
3445        let (prefix, suffix) =
3446            unsafe { SplitAt::split_at_unchecked(source, split_at) }.via_immutable();
3447        match try_read_from(suffix) {
3448            Ok(slf) => Ok((prefix, slf)),
3449            Err(e) => Err(e.map_src(
3450                #[inline(always)]
3451                |_| source,
3452            )),
3453        }
3454    }
3455}
3456
3457/// Validates and interprets the given affix of `source`'s bytes as a `&T`.
3458///
3459/// Returns the destination reference and excess bytes on success. All errors,
3460/// including validity errors, contain the original `&S`.
3461#[inline(always)]
3462fn try_ref_from_prefix_suffix<S, T>(
3463    source: &S,
3464    cast_type: CastType,
3465    meta: Option<T::PointerMetadata>,
3466) -> Result<(&T, &[u8]), TryCastError<&S, T>>
3467where
3468    S: IntoBytes + Immutable + ?Sized,
3469    T: TryFromBytes + KnownLayout + Immutable + ?Sized,
3470{
3471    match Ptr::from_ref(source.as_bytes()).try_cast_into::<T, BecauseImmutable>(cast_type, meta) {
3472        Ok((candidate, prefix_suffix)) => {
3473            // This call may panic. If that happens, it doesn't cause any soundness
3474            // issues, as we have not generated any invalid state which we need to
3475            // fix before returning.
3476            match candidate.try_into_safe() {
3477                Ok(valid) => Ok((valid.as_ref(), prefix_suffix.as_ref())),
3478                Err(e) => Err(e
3479                    .map_src(
3480                        #[inline(always)]
3481                        |_| source,
3482                    )
3483                    .into()),
3484            }
3485        }
3486        Err(e) => Err(e
3487            .map_src(
3488                #[inline(always)]
3489                |_| source,
3490            )
3491            .into()),
3492    }
3493}
3494
3495#[inline(always)]
3496fn try_mut_from_prefix_suffix<T: IntoBytes + TryFromBytes + KnownLayout + ?Sized>(
3497    candidate: &mut [u8],
3498    cast_type: CastType,
3499    meta: Option<T::PointerMetadata>,
3500) -> Result<(&mut T, &mut [u8]), TryCastError<&mut [u8], T>> {
3501    match Ptr::from_mut(candidate).try_cast_into::<T, BecauseExclusive>(cast_type, meta) {
3502        Ok((candidate, prefix_suffix)) => {
3503            // This call may panic. If that happens, it doesn't cause any soundness
3504            // issues, as we have not generated any invalid state which we need to
3505            // fix before returning.
3506            match candidate.try_into_safe() {
3507                Ok(valid) => Ok((valid.as_mut(), prefix_suffix.as_mut())),
3508                Err(e) => Err(e.map_src(|src| src.as_bytes().as_mut()).into()),
3509            }
3510        }
3511        Err(e) => Err(e.map_src(Ptr::as_mut).into()),
3512    }
3513}
3514
3515#[inline(always)]
3516fn swap<T, U>((t, u): (T, U)) -> (U, T) {
3517    (u, t)
3518}
3519
3520#[inline(always)]
3521fn try_read_from<S, T>(source: &S) -> Result<T, TryReadError<&S, T>>
3522where
3523    S: IntoBytes + Immutable + ?Sized,
3524    T: TryFromBytes,
3525{
3526    let bytes = source.as_bytes();
3527
3528    if bytes.len() != mem::size_of::<T>() {
3529        return Err(SizeError::new(source).into());
3530    }
3531
3532    // FIXME(#2981): Avoid the validation copy when validation can safely use
3533    // a pointer derived from `source`'s shared borrow.
3534
3535    // Initialize the candidate in its final location. A typed move of a
3536    // `MaybeUninit<T>` may discard initialized bytes at `T`'s padding offsets
3537    // [1], but validation requires every byte to be initialized. Do not move
3538    // `candidate` between this copy and validation.
3539    //
3540    // [1] Per https://doc.rust-lang.org/1.93.1/std/mem/union.MaybeUninit.html#validity:
3541    //
3542    //   Moving or copying a value of type `MaybeUninit<T>` (i.e., performing a
3543    //   "typed copy") will exactly preserve the contents, including the
3544    //   provenance, of all non-padding bytes of type `T` in the value's
3545    //   representation.
3546    let mut candidate = CoreMaybeUninit::<T>::uninit();
3547
3548    // SAFETY: The earlier `if bytes.len() != mem::size_of::<T>()` returns on a
3549    // size mismatch, so reaching this copy implies that `bytes.len()` equals
3550    // `mem::size_of::<T>()`. Copying that many `u8`s cannot overrun `bytes`.
3551    // `candidate.as_mut_ptr()` is writable for the same number of bytes because
3552    // `MaybeUninit<T>` has `T`'s size. Both pointers are non-null and aligned
3553    // for `u8`, including when `T` is zero-sized. The fresh local allocation
3554    // cannot overlap `source`, which is an argument. Thus the read, write,
3555    // alignment, and non-overlap requirements of [2] hold. Copying `u8`s
3556    // initializes every destination byte, including those at `T`'s padding
3557    // offsets.
3558    //
3559    // These writes cannot violate `candidate`'s bit validity because every bit
3560    // pattern is valid for `MaybeUninit<T>` [3], even if it is invalid for `T`.
3561    //
3562    // [2] Per https://doc.rust-lang.org/1.56.0/std/ptr/fn.copy_nonoverlapping.html:
3563    //
3564    //   Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
3565    //   and destination must *not* overlap.
3566    //
3567    // [3] Per https://doc.rust-lang.org/1.56.0/std/mem/union.MaybeUninit.html#layout:
3568    //
3569    //   ... any bit value is valid for a `MaybeUninit<T>` ...
3570    unsafe {
3571        ptr::copy_nonoverlapping(
3572            bytes.as_ptr(),
3573            candidate.as_mut_ptr().cast::<u8>(),
3574            mem::size_of::<T>(),
3575        );
3576    }
3577
3578    // We use `from_mut` despite not mutating via `c_ptr` so that we don't need
3579    // to add a `T: Immutable` bound.
3580    let c_ptr = Ptr::from_mut(&mut candidate);
3581
3582    // SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived from
3583    // `candidate`, whose bytes were all initialized by the copy above and which
3584    // has not been moved since. Since `candidate` is a `MaybeUninit`, it has no
3585    // validity requirements, and so no values written to an `Initialized`
3586    // `c_ptr` can violate its validity. Since `c_ptr` has `Exclusive` aliasing,
3587    // no mutations may happen except via `c_ptr` so long as it is live, so we
3588    // don't need to worry about the fact that `c_ptr` may have more restricted
3589    // validity than `candidate`.
3590    let c_ptr = unsafe { c_ptr.assume_validity::<invariant::Initialized>() };
3591
3592    let c_ptr = c_ptr.cast::<_, crate::pointer::cast::CastSized, _>();
3593
3594    // SAFETY: `c_ptr` originated from a reference to `candidate`, so its
3595    // address is aligned for `MaybeUninit<T>`, which has `T`'s alignment [1].
3596    // `CastSized` preserves that address. `ReadOnly<T>` is `repr(transparent)`
3597    // with a single `T` field, so it also has `T`'s alignment [2], including
3598    // when `T` is zero-sized.
3599    //
3600    // [1] Per https://doc.rust-lang.org/1.56.0/std/mem/union.MaybeUninit.html#layout:
3601    //
3602    //   `MaybeUninit<T>` is guaranteed to have the same size, alignment, and
3603    //   ABI as `T`:
3604    //
3605    // [2] Per https://doc.rust-lang.org/1.93.1/reference/type-layout.html#the-transparent-representation:
3606    //
3607    //   ... same layout and ABI as the only non-size 0 non-alignment 1 field,
3608    //   if present, or unit otherwise.
3609    let mut c_ptr = unsafe { c_ptr.assume_alignment::<invariant::Aligned>() };
3610
3611    // This call may panic. If that happens, it doesn't cause any soundness
3612    // issues, as we have not generated any invalid state which we need to fix
3613    // before returning.
3614    if !T::is_safe(c_ptr.reborrow_shared()) {
3615        return Err(ValidityError::new(source).into());
3616    }
3617
3618    // SAFETY: `T::is_safe` returned true for `candidate`'s initialized bytes,
3619    // so it contains a valid `T`, as required by [1]. Validation used a shared
3620    // `ReadOnly<T>` pointer, and the bytes have not been modified since.
3621    //
3622    // [1] Per https://doc.rust-lang.org/1.56.0/std/mem/union.MaybeUninit.html#method.assume_init:
3623    //
3624    //   It is up to the caller to guarantee that the `MaybeUninit<T>` really is
3625    //   in an initialized state.
3626    Ok(unsafe { candidate.assume_init() })
3627}
3628
3629/// Types for which a sequence of `0` bytes is a valid instance.
3630///
3631/// Any memory region of the appropriate length which is guaranteed to contain
3632/// only zero bytes can be viewed as any `FromZeros` type with no runtime
3633/// overhead. This is useful whenever memory is known to be in a zeroed state,
3634/// such memory returned from some allocation routines.
3635///
3636/// # Warning: Padding bytes
3637///
3638/// Note that, when a value is moved or copied, only the non-padding bytes of
3639/// that value are guaranteed to be preserved. It is unsound to assume that
3640/// values written to padding bytes are preserved after a move or copy. For more
3641/// details, see the [`FromBytes` docs][frombytes-warning-padding-bytes].
3642///
3643/// [frombytes-warning-padding-bytes]: FromBytes#warning-padding-bytes
3644///
3645/// # Implementation
3646///
3647/// **Do not implement this trait yourself!** Instead, use
3648/// [`#[derive(FromZeros)]`][derive]; e.g.:
3649///
3650/// ```
3651/// # use zerocopy_derive::{FromZeros, Immutable};
3652/// #[derive(FromZeros)]
3653/// struct MyStruct {
3654/// # /*
3655///     ...
3656/// # */
3657/// }
3658///
3659/// #[derive(FromZeros)]
3660/// #[repr(u8)]
3661/// enum MyEnum {
3662/// #   Variant0,
3663/// # /*
3664///     ...
3665/// # */
3666/// }
3667///
3668/// #[derive(FromZeros, Immutable)]
3669/// union MyUnion {
3670/// #   variant: u8,
3671/// # /*
3672///     ...
3673/// # */
3674/// }
3675/// ```
3676///
3677/// This derive performs a sophisticated, compile-time safety analysis to
3678/// determine whether a type is `FromZeros`.
3679///
3680/// # Safety
3681///
3682/// *This section describes what is required in order for `T: FromZeros`, and
3683/// what unsafe code may assume of such types. If you don't plan on implementing
3684/// `FromZeros` manually, and you don't plan on writing unsafe code that
3685/// operates on `FromZeros` types, then you don't need to read this section.*
3686///
3687/// If `T: FromZeros`, then unsafe code may assume that it is sound to produce a
3688/// `T` whose bytes are all initialized to zero. If a type is marked as
3689/// `FromZeros` which violates this contract, it may cause undefined behavior.
3690///
3691/// `#[derive(FromZeros)]` only permits [types which satisfy these
3692/// requirements][derive-analysis].
3693///
3694#[cfg_attr(
3695    feature = "derive",
3696    doc = "[derive]: zerocopy_derive::FromZeros",
3697    doc = "[derive-analysis]: zerocopy_derive::FromZeros#analysis"
3698)]
3699#[cfg_attr(
3700    not(feature = "derive"),
3701    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeros.html"),
3702    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeros.html#analysis"),
3703)]
3704#[cfg_attr(
3705    not(no_zerocopy_diagnostic_on_unimplemented_1_78_0),
3706    diagnostic::on_unimplemented(note = "Consider adding `#[derive(FromZeros)]` to `{Self}`")
3707)]
3708pub unsafe trait FromZeros: TryFromBytes {
3709    // The `Self: Sized` bound makes it so that `FromZeros` is still object
3710    // safe.
3711    #[doc(hidden)]
3712    fn only_derive_is_allowed_to_implement_this_trait()
3713    where
3714        Self: Sized;
3715
3716    /// Overwrites `self` with zeros.
3717    ///
3718    /// Sets every byte in `self` to 0. While this is similar to doing `*self =
3719    /// Self::new_zeroed()`, it differs in that `zero` does not semantically
3720    /// drop the current value and replace it with a new one — it simply
3721    /// modifies the bytes of the existing value.
3722    ///
3723    /// # Examples
3724    ///
3725    /// ```
3726    /// # use zerocopy::FromZeros;
3727    /// # use zerocopy_derive::*;
3728    /// #
3729    /// #[derive(FromZeros)]
3730    /// #[repr(C)]
3731    /// struct PacketHeader {
3732    ///     src_port: [u8; 2],
3733    ///     dst_port: [u8; 2],
3734    ///     length: [u8; 2],
3735    ///     checksum: [u8; 2],
3736    /// }
3737    ///
3738    /// let mut header = PacketHeader {
3739    ///     src_port: 100u16.to_be_bytes(),
3740    ///     dst_port: 200u16.to_be_bytes(),
3741    ///     length: 300u16.to_be_bytes(),
3742    ///     checksum: 400u16.to_be_bytes(),
3743    /// };
3744    ///
3745    /// header.zero();
3746    ///
3747    /// assert_eq!(header.src_port, [0, 0]);
3748    /// assert_eq!(header.dst_port, [0, 0]);
3749    /// assert_eq!(header.length, [0, 0]);
3750    /// assert_eq!(header.checksum, [0, 0]);
3751    /// ```
3752    ///
3753    #[doc = codegen_section!(
3754        header = "h5",
3755        bench = "zero",
3756        format = "coco",
3757        arity = 3,
3758        [
3759            open
3760            @index 1
3761            @title "Sized"
3762            @variant "static_size"
3763        ],
3764        [
3765            @index 2
3766            @title "Unsized"
3767            @variant "dynamic_size"
3768        ],
3769        [
3770            @index 3
3771            @title "Dynamically Padded"
3772            @variant "dynamic_padding"
3773        ]
3774    )]
3775    #[inline(always)]
3776    fn zero(&mut self) {
3777        let slf: *mut Self = self;
3778        let len = mem::size_of_val(self);
3779        // SAFETY:
3780        // - `self` is guaranteed by the type system to be valid for writes of
3781        //   size `size_of_val(self)`.
3782        // - `u8`'s alignment is 1, and thus `self` is guaranteed to be aligned
3783        //   as required by `u8`.
3784        // - Since `Self: FromZeros`, the all-zeros instance is a valid instance
3785        //   of `Self.`
3786        //
3787        // FIXME(#429): Add references to docs and quotes.
3788        unsafe { ptr::write_bytes(slf.cast::<u8>(), 0, len) };
3789    }
3790
3791    /// Creates an instance of `Self` from zeroed bytes.
3792    ///
3793    /// # Examples
3794    ///
3795    /// ```
3796    /// # use zerocopy::FromZeros;
3797    /// # use zerocopy_derive::*;
3798    /// #
3799    /// #[derive(FromZeros)]
3800    /// #[repr(C)]
3801    /// struct PacketHeader {
3802    ///     src_port: [u8; 2],
3803    ///     dst_port: [u8; 2],
3804    ///     length: [u8; 2],
3805    ///     checksum: [u8; 2],
3806    /// }
3807    ///
3808    /// let header: PacketHeader = FromZeros::new_zeroed();
3809    ///
3810    /// assert_eq!(header.src_port, [0, 0]);
3811    /// assert_eq!(header.dst_port, [0, 0]);
3812    /// assert_eq!(header.length, [0, 0]);
3813    /// assert_eq!(header.checksum, [0, 0]);
3814    /// ```
3815    ///
3816    #[doc = codegen_section!(
3817        header = "h5",
3818        bench = "new_zeroed",
3819        format = "coco_static_size",
3820    )]
3821    #[must_use = "has no side effects"]
3822    #[inline(always)]
3823    fn new_zeroed() -> Self
3824    where
3825        Self: Sized,
3826    {
3827        // SAFETY: `FromZeros` says that the all-zeros bit pattern is legal.
3828        unsafe { mem::zeroed() }
3829    }
3830
3831    /// Creates a `Box<Self>` from zeroed bytes.
3832    ///
3833    /// This function is useful for allocating large values on the heap and
3834    /// zero-initializing them, without ever creating a temporary instance of
3835    /// `Self` on the stack. For example, `<[u8; 1048576]>::new_box_zeroed()`
3836    /// will allocate `[u8; 1048576]` directly on the heap; it does not require
3837    /// storing `[u8; 1048576]` in a temporary variable on the stack.
3838    ///
3839    /// On systems that use a heap implementation that supports allocating from
3840    /// pre-zeroed memory, using `new_box_zeroed` (or related functions) may
3841    /// have performance benefits.
3842    ///
3843    /// # Errors
3844    ///
3845    /// Returns an error on allocation failure. Allocation failure is guaranteed
3846    /// never to cause a panic or an abort.
3847    ///
3848    #[doc = codegen_section!(
3849        header = "h5",
3850        bench = "new_box_zeroed",
3851        format = "coco_static_size",
3852    )]
3853    #[must_use = "has no side effects (other than allocation)"]
3854    #[cfg(any(feature = "alloc", test))]
3855    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3856    #[inline]
3857    fn new_box_zeroed() -> Result<Box<Self>, AllocError>
3858    where
3859        Self: Sized,
3860    {
3861        // If `T` is a ZST, then return a proper boxed instance of it. There is
3862        // no allocation, but `Box` does require a correct dangling pointer.
3863        let layout = Layout::new::<Self>();
3864        if layout.size() == 0 {
3865            // Construct the `Box` from a dangling pointer to avoid calling
3866            // `Self::new_zeroed`. This ensures that stack space is never
3867            // allocated for `Self` even on lower opt-levels where this branch
3868            // might not get optimized out.
3869
3870            // SAFETY: Per [1], when `T` is a ZST, `Box<T>`'s only validity
3871            // requirements are that the pointer is non-null and sufficiently
3872            // aligned. Per [2], `NonNull::dangling` produces a pointer which
3873            // is sufficiently aligned. Since the produced pointer is a
3874            // `NonNull`, it is non-null.
3875            //
3876            // [1] Per https://doc.rust-lang.org/1.81.0/std/boxed/index.html#memory-layout:
3877            //
3878            //   For zero-sized values, the `Box` pointer has to be non-null and sufficiently aligned.
3879            //
3880            // [2] Per https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.dangling:
3881            //
3882            //   Creates a new `NonNull` that is dangling, but well-aligned.
3883            return Ok(unsafe { Box::from_raw(NonNull::dangling().as_ptr()) });
3884        }
3885
3886        // FIXME(#429): Add a "SAFETY" comment and remove this `allow`.
3887        #[allow(clippy::undocumented_unsafe_blocks)]
3888        let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
3889        if ptr.is_null() {
3890            return Err(AllocError);
3891        }
3892        // FIXME(#429): Add a "SAFETY" comment and remove this `allow`.
3893        #[allow(clippy::undocumented_unsafe_blocks)]
3894        Ok(unsafe { Box::from_raw(ptr) })
3895    }
3896
3897    /// Creates a `Box<[Self]>` (a boxed slice) from zeroed bytes.
3898    ///
3899    /// This function is useful for allocating large values of `[Self]` on the
3900    /// heap and zero-initializing them, without ever creating a temporary
3901    /// instance of `[Self; _]` on the stack. For example,
3902    /// `u8::new_box_slice_zeroed(1048576)` will allocate the slice directly on
3903    /// the heap; it does not require storing the slice on the stack.
3904    ///
3905    /// On systems that use a heap implementation that supports allocating from
3906    /// pre-zeroed memory, using `new_box_slice_zeroed` may have performance
3907    /// benefits.
3908    ///
3909    /// If `Self` is a zero-sized type, then this function will return a
3910    /// `Box<[Self]>` that has the correct `len`. Such a box cannot contain any
3911    /// actual information, but its `len()` property will report the correct
3912    /// value.
3913    ///
3914    /// # Errors
3915    ///
3916    /// Returns an error on allocation failure. Allocation failure is
3917    /// guaranteed never to cause a panic or an abort.
3918    ///
3919    #[doc = codegen_section!(
3920        header = "h5",
3921        bench = "new_box_zeroed_with_elems",
3922        format = "coco",
3923        arity = 2,
3924        [
3925            open
3926            @index 1
3927            @title "Unsized"
3928            @variant "dynamic_size"
3929        ],
3930        [
3931            @index 2
3932            @title "Dynamically Padded"
3933            @variant "dynamic_padding"
3934        ]
3935    )]
3936    #[must_use = "has no side effects (other than allocation)"]
3937    #[cfg(feature = "alloc")]
3938    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3939    #[inline]
3940    fn new_box_zeroed_with_elems(count: usize) -> Result<Box<Self>, AllocError>
3941    where
3942        Self: KnownLayout<PointerMetadata = usize>,
3943    {
3944        // SAFETY: `alloc::alloc::alloc_zeroed` is a valid argument of
3945        // `new_box`. The referent of the pointer returned by `alloc_zeroed`
3946        // (and, consequently, the `Box` derived from it) is a valid instance of
3947        // `Self`, because `Self` is `FromZeros`.
3948        unsafe { crate::util::new_box(count, alloc::alloc::alloc_zeroed) }
3949    }
3950
3951    #[deprecated(since = "0.8.0", note = "renamed to `FromZeros::new_box_zeroed_with_elems`")]
3952    #[doc(hidden)]
3953    #[cfg(feature = "alloc")]
3954    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3955    #[must_use = "has no side effects (other than allocation)"]
3956    #[inline(always)]
3957    fn new_box_slice_zeroed(len: usize) -> Result<Box<[Self]>, AllocError>
3958    where
3959        Self: Sized,
3960    {
3961        <[Self]>::new_box_zeroed_with_elems(len)
3962    }
3963
3964    /// Creates a `Vec<Self>` from zeroed bytes.
3965    ///
3966    /// This function is useful for allocating large values of `Vec`s and
3967    /// zero-initializing them, without ever creating a temporary instance of
3968    /// `[Self; _]` (or many temporary instances of `Self`) on the stack. For
3969    /// example, `u8::new_vec_zeroed(1048576)` will allocate directly on the
3970    /// heap; it does not require storing intermediate values on the stack.
3971    ///
3972    /// On systems that use a heap implementation that supports allocating from
3973    /// pre-zeroed memory, using `new_vec_zeroed` may have performance benefits.
3974    ///
3975    /// If `Self` is a zero-sized type, then this function will return a
3976    /// `Vec<Self>` that has the correct `len`. Such a `Vec` cannot contain any
3977    /// actual information, but its `len()` property will report the correct
3978    /// value.
3979    ///
3980    /// # Errors
3981    ///
3982    /// Returns an error on allocation failure. Allocation failure is
3983    /// guaranteed never to cause a panic or an abort.
3984    ///
3985    #[doc = codegen_section!(
3986        header = "h5",
3987        bench = "new_vec_zeroed",
3988        format = "coco_static_size",
3989    )]
3990    #[must_use = "has no side effects (other than allocation)"]
3991    #[cfg(feature = "alloc")]
3992    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3993    #[inline(always)]
3994    fn new_vec_zeroed(len: usize) -> Result<Vec<Self>, AllocError>
3995    where
3996        Self: Sized,
3997    {
3998        <[Self]>::new_box_zeroed_with_elems(len).map(Into::into)
3999    }
4000
4001    /// Extends a `Vec<Self>` by pushing `additional` new items onto the end of
4002    /// the vector. The new items are initialized with zeros.
4003    ///
4004    #[doc = codegen_section!(
4005        header = "h5",
4006        bench = "extend_vec_zeroed",
4007        format = "coco_static_size",
4008    )]
4009    #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
4010    #[cfg(feature = "alloc")]
4011    #[cfg_attr(doc_cfg, doc(cfg(all(rust = "1.57.0", feature = "alloc"))))]
4012    #[inline(always)]
4013    fn extend_vec_zeroed(v: &mut Vec<Self>, additional: usize) -> Result<(), AllocError>
4014    where
4015        Self: Sized,
4016    {
4017        // PANICS: We pass `v.len()` for `position`, so the `position > v.len()`
4018        // panic condition is not satisfied.
4019        <Self as FromZeros>::insert_vec_zeroed(v, v.len(), additional)
4020    }
4021
4022    /// Inserts `additional` new items into `Vec<Self>` at `position`. The new
4023    /// items are initialized with zeros.
4024    ///
4025    /// # Panics
4026    ///
4027    /// Panics if `position > v.len()`.
4028    ///
4029    #[doc = codegen_section!(
4030        header = "h5",
4031        bench = "insert_vec_zeroed",
4032        format = "coco_static_size",
4033    )]
4034    #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
4035    #[cfg(feature = "alloc")]
4036    #[cfg_attr(doc_cfg, doc(cfg(all(rust = "1.57.0", feature = "alloc"))))]
4037    #[inline]
4038    fn insert_vec_zeroed(
4039        v: &mut Vec<Self>,
4040        position: usize,
4041        additional: usize,
4042    ) -> Result<(), AllocError>
4043    where
4044        Self: Sized,
4045    {
4046        assert!(position <= v.len());
4047        // We only conditionally compile on versions on which `try_reserve` is
4048        // stable; the Clippy lint is a false positive.
4049        v.try_reserve(additional).map_err(|_| AllocError)?;
4050        // SAFETY: The `try_reserve` call guarantees that these cannot overflow:
4051        // * `ptr.add(position)`
4052        // * `position + additional`
4053        // * `v.len() + additional`
4054        //
4055        // `v.len() - position` cannot overflow because we asserted that
4056        // `position <= v.len()`.
4057        #[allow(clippy::multiple_unsafe_ops_per_block)]
4058        unsafe {
4059            // This is a potentially overlapping copy.
4060            let ptr = v.as_mut_ptr();
4061            #[allow(clippy::arithmetic_side_effects)]
4062            ptr.add(position).copy_to(ptr.add(position + additional), v.len() - position);
4063            ptr.add(position).write_bytes(0, additional);
4064            #[allow(clippy::arithmetic_side_effects)]
4065            v.set_len(v.len() + additional);
4066        }
4067
4068        Ok(())
4069    }
4070}
4071
4072/// Analyzes whether a type is [`FromBytes`].
4073///
4074/// This derive analyzes, at compile time, whether the annotated type satisfies
4075/// the [safety conditions] of `FromBytes` and implements `FromBytes` and its
4076/// supertraits if it is sound to do so. This derive can be applied to structs,
4077/// enums, and unions;
4078/// e.g.:
4079///
4080/// ```
4081/// # use zerocopy_derive::{FromBytes, FromZeros, Immutable};
4082/// #[derive(FromBytes)]
4083/// struct MyStruct {
4084/// # /*
4085///     ...
4086/// # */
4087/// }
4088///
4089/// #[derive(FromBytes)]
4090/// #[repr(u8)]
4091/// enum MyEnum {
4092/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
4093/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
4094/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
4095/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
4096/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
4097/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
4098/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
4099/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
4100/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
4101/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
4102/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
4103/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
4104/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
4105/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
4106/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
4107/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
4108/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
4109/// #   VFF,
4110/// # /*
4111///     ...
4112/// # */
4113/// }
4114///
4115/// #[derive(FromBytes, Immutable)]
4116/// union MyUnion {
4117/// #   variant: u8,
4118/// # /*
4119///     ...
4120/// # */
4121/// }
4122/// ```
4123///
4124/// [safety conditions]: trait@FromBytes#safety
4125///
4126/// # Analysis
4127///
4128/// *This section describes, roughly, the analysis performed by this derive to
4129/// determine whether it is sound to implement `FromBytes` for a given type.
4130/// Unless you are modifying the implementation of this derive, or attempting to
4131/// manually implement `FromBytes` for a type yourself, you don't need to read
4132/// this section.*
4133///
4134/// If a type has the following properties, then this derive can implement
4135/// `FromBytes` for that type:
4136///
4137/// - If the type is a struct, all of its fields must be `FromBytes`.
4138/// - If the type is an enum:
4139///   - It must have a defined representation which is one of `u8`, `u16`, `i8`,
4140///     or `i16`.
4141///   - The maximum number of discriminants must be used (so that every possible
4142///     bit pattern is a valid one).
4143///   - Its fields must be `FromBytes`.
4144///
4145/// This analysis is subject to change. Unsafe code may *only* rely on the
4146/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
4147/// implementation details of this derive.
4148///
4149/// ## Why isn't an explicit representation required for structs?
4150///
4151/// Neither this derive, nor the [safety conditions] of `FromBytes`, requires
4152/// that structs are marked with `#[repr(C)]`.
4153///
4154/// Per the [Rust reference](reference),
4155///
4156/// > The representation of a type can change the padding between fields, but
4157/// > does not change the layout of the fields themselves.
4158///
4159/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
4160///
4161/// Since the layout of structs only consists of padding bytes and field bytes,
4162/// a struct is soundly `FromBytes` if:
4163/// 1. its padding is soundly `FromBytes`, and
4164/// 2. its fields are soundly `FromBytes`.
4165///
4166/// The answer to the first question is always yes: padding bytes do not have
4167/// any validity constraints. A [discussion] of this question in the Unsafe Code
4168/// Guidelines Working Group concluded that it would be virtually unimaginable
4169/// for future versions of rustc to add validity constraints to padding bytes.
4170///
4171/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
4172///
4173/// Whether a struct is soundly `FromBytes` therefore solely depends on whether
4174/// its fields are `FromBytes`.
4175#[cfg(any(feature = "derive", test))]
4176#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
4177pub use zerocopy_derive::FromBytes;
4178
4179/// Types for which any bit pattern is valid.
4180///
4181/// Any memory region of the appropriate length which contains initialized bytes
4182/// can be viewed as any `FromBytes` type with no runtime overhead. This is
4183/// useful for efficiently parsing bytes as structured data.
4184///
4185/// # Warning: Padding bytes
4186///
4187/// Note that, when a value is moved or copied, only the non-padding bytes of
4188/// that value are guaranteed to be preserved. It is unsound to assume that
4189/// values written to padding bytes are preserved after a move or copy. For
4190/// example, the following is unsound:
4191///
4192/// ```rust,no_run
4193/// use core::mem::{size_of, transmute};
4194/// use zerocopy::FromZeros;
4195/// # use zerocopy_derive::*;
4196///
4197/// // Assume `Foo` is a type with padding bytes.
4198/// #[derive(FromZeros, Default)]
4199/// struct Foo {
4200/// # /*
4201///     ...
4202/// # */
4203/// }
4204///
4205/// let mut foo: Foo = Foo::default();
4206/// FromZeros::zero(&mut foo);
4207/// // UNSOUND: Although `FromZeros::zero` writes zeros to all bytes of `foo`,
4208/// // those writes are not guaranteed to be preserved in padding bytes when
4209/// // `foo` is moved, so this may expose padding bytes as `u8`s.
4210/// let foo_bytes: [u8; size_of::<Foo>()] = unsafe { transmute(foo) };
4211/// ```
4212///
4213/// # Implementation
4214///
4215/// **Do not implement this trait yourself!** Instead, use
4216/// [`#[derive(FromBytes)]`][derive]; e.g.:
4217///
4218/// ```
4219/// # use zerocopy_derive::{FromBytes, Immutable};
4220/// #[derive(FromBytes)]
4221/// struct MyStruct {
4222/// # /*
4223///     ...
4224/// # */
4225/// }
4226///
4227/// #[derive(FromBytes)]
4228/// #[repr(u8)]
4229/// enum MyEnum {
4230/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
4231/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
4232/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
4233/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
4234/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
4235/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
4236/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
4237/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
4238/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
4239/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
4240/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
4241/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
4242/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
4243/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
4244/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
4245/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
4246/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
4247/// #   VFF,
4248/// # /*
4249///     ...
4250/// # */
4251/// }
4252///
4253/// #[derive(FromBytes, Immutable)]
4254/// union MyUnion {
4255/// #   variant: u8,
4256/// # /*
4257///     ...
4258/// # */
4259/// }
4260/// ```
4261///
4262/// This derive performs a sophisticated, compile-time safety analysis to
4263/// determine whether a type is `FromBytes`.
4264///
4265/// # Safety
4266///
4267/// *This section describes what is required in order for `T: FromBytes`, and
4268/// what unsafe code may assume of such types. If you don't plan on implementing
4269/// `FromBytes` manually, and you don't plan on writing unsafe code that
4270/// operates on `FromBytes` types, then you don't need to read this section.*
4271///
4272/// If `T: FromBytes`, then unsafe code may assume that it is sound to produce a
4273/// `T` whose bytes are initialized to any sequence of valid `u8`s (in other
4274/// words, any byte value which is not uninitialized). If a type is marked as
4275/// `FromBytes` which violates this contract, it may cause undefined behavior.
4276///
4277/// `#[derive(FromBytes)]` only permits [types which satisfy these
4278/// requirements][derive-analysis].
4279///
4280#[cfg_attr(
4281    feature = "derive",
4282    doc = "[derive]: zerocopy_derive::FromBytes",
4283    doc = "[derive-analysis]: zerocopy_derive::FromBytes#analysis"
4284)]
4285#[cfg_attr(
4286    not(feature = "derive"),
4287    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html"),
4288    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html#analysis"),
4289)]
4290#[cfg_attr(
4291    not(no_zerocopy_diagnostic_on_unimplemented_1_78_0),
4292    diagnostic::on_unimplemented(note = "Consider adding `#[derive(FromBytes)]` to `{Self}`")
4293)]
4294pub unsafe trait FromBytes: FromZeros {
4295    // The `Self: Sized` bound makes it so that `FromBytes` is still object
4296    // safe.
4297    #[doc(hidden)]
4298    fn only_derive_is_allowed_to_implement_this_trait()
4299    where
4300        Self: Sized;
4301
4302    /// Interprets the given `source` as a `&Self`.
4303    ///
4304    /// This method attempts to return a reference to `source` interpreted as a
4305    /// `Self`. If the length of `source` is not a [valid size of
4306    /// `Self`][valid-size], or if `source` is not appropriately aligned, this
4307    /// returns `Err`. If [`Self: Unaligned`][self-unaligned], you can
4308    /// [infallibly discard the alignment error][size-error-from].
4309    ///
4310    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
4311    ///
4312    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
4313    /// [self-unaligned]: Unaligned
4314    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4315    /// [slice-dst]: KnownLayout#dynamically-sized-types
4316    ///
4317    /// # Compile-Time Assertions
4318    ///
4319    /// This method cannot yet be used on unsized types whose dynamically-sized
4320    /// component is zero-sized. Attempting to use this method on such types
4321    /// results in a compile-time assertion error; e.g.:
4322    ///
4323    /// ```compile_fail,E0080
4324    /// use zerocopy::*;
4325    /// # use zerocopy_derive::*;
4326    ///
4327    /// #[derive(FromBytes, Immutable, KnownLayout)]
4328    /// #[repr(C)]
4329    /// struct ZSTy {
4330    ///     leading_sized: u16,
4331    ///     trailing_dst: [()],
4332    /// }
4333    ///
4334    /// let _ = ZSTy::ref_from_bytes(0u16.as_bytes()); // âš  Compile Error!
4335    /// ```
4336    ///
4337    /// # Examples
4338    ///
4339    /// ```
4340    /// use zerocopy::FromBytes;
4341    /// # use zerocopy_derive::*;
4342    ///
4343    /// #[derive(FromBytes, KnownLayout, Immutable)]
4344    /// #[repr(C)]
4345    /// struct PacketHeader {
4346    ///     src_port: [u8; 2],
4347    ///     dst_port: [u8; 2],
4348    ///     length: [u8; 2],
4349    ///     checksum: [u8; 2],
4350    /// }
4351    ///
4352    /// #[derive(FromBytes, KnownLayout, Immutable)]
4353    /// #[repr(C)]
4354    /// struct Packet {
4355    ///     header: PacketHeader,
4356    ///     body: [u8],
4357    /// }
4358    ///
4359    /// // These bytes encode a `Packet`.
4360    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11][..];
4361    ///
4362    /// let packet = Packet::ref_from_bytes(bytes).unwrap();
4363    ///
4364    /// assert_eq!(packet.header.src_port, [0, 1]);
4365    /// assert_eq!(packet.header.dst_port, [2, 3]);
4366    /// assert_eq!(packet.header.length, [4, 5]);
4367    /// assert_eq!(packet.header.checksum, [6, 7]);
4368    /// assert_eq!(packet.body, [8, 9, 10, 11]);
4369    /// ```
4370    ///
4371    #[doc = codegen_section!(
4372        header = "h5",
4373        bench = "ref_from_bytes",
4374        format = "coco",
4375        arity = 3,
4376        [
4377            open
4378            @index 1
4379            @title "Sized"
4380            @variant "static_size"
4381        ],
4382        [
4383            @index 2
4384            @title "Unsized"
4385            @variant "dynamic_size"
4386        ],
4387        [
4388            @index 3
4389            @title "Dynamically Padded"
4390            @variant "dynamic_padding"
4391        ]
4392    )]
4393    #[must_use = "has no side effects"]
4394    #[cfg_attr(zerocopy_inline_always, inline(always))]
4395    #[cfg_attr(not(zerocopy_inline_always), inline)]
4396    fn ref_from_bytes(source: &[u8]) -> Result<&Self, CastError<&[u8], Self>>
4397    where
4398        Self: KnownLayout + Immutable,
4399    {
4400        static_assert_dst_is_not_zst!(Self);
4401        match Ptr::from_ref(source).try_cast_into_no_leftover::<_, BecauseImmutable>(None) {
4402            Ok(ptr) => Ok(ptr.recall_validity().as_ref()),
4403            Err(err) => Err(err.map_src(|src| src.as_ref())),
4404        }
4405    }
4406
4407    /// Interprets the prefix of the given `source` as a `&Self` without
4408    /// copying.
4409    ///
4410    /// This method computes the [largest possible size of `Self`][valid-size]
4411    /// that can fit in the leading bytes of `source`, then attempts to return
4412    /// both a reference to those bytes interpreted as a `Self`, and a reference
4413    /// to the remaining bytes. If there are insufficient bytes, or if `source`
4414    /// is not appropriately aligned, this returns `Err`. If [`Self:
4415    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
4416    /// error][size-error-from].
4417    ///
4418    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
4419    ///
4420    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
4421    /// [self-unaligned]: Unaligned
4422    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4423    /// [slice-dst]: KnownLayout#dynamically-sized-types
4424    ///
4425    /// # Compile-Time Assertions
4426    ///
4427    /// This method cannot yet be used on unsized types whose dynamically-sized
4428    /// component is zero-sized. See [`ref_from_prefix_with_elems`], which does
4429    /// support such types. Attempting to use this method on such types results
4430    /// in a compile-time assertion error; e.g.:
4431    ///
4432    /// ```compile_fail,E0080
4433    /// use zerocopy::*;
4434    /// # use zerocopy_derive::*;
4435    ///
4436    /// #[derive(FromBytes, Immutable, KnownLayout)]
4437    /// #[repr(C)]
4438    /// struct ZSTy {
4439    ///     leading_sized: u16,
4440    ///     trailing_dst: [()],
4441    /// }
4442    ///
4443    /// let _ = ZSTy::ref_from_prefix(0u16.as_bytes()); // âš  Compile Error!
4444    /// ```
4445    ///
4446    /// [`ref_from_prefix_with_elems`]: FromBytes::ref_from_prefix_with_elems
4447    ///
4448    /// # Examples
4449    ///
4450    /// ```
4451    /// use zerocopy::FromBytes;
4452    /// # use zerocopy_derive::*;
4453    ///
4454    /// #[derive(FromBytes, KnownLayout, Immutable)]
4455    /// #[repr(C)]
4456    /// struct PacketHeader {
4457    ///     src_port: [u8; 2],
4458    ///     dst_port: [u8; 2],
4459    ///     length: [u8; 2],
4460    ///     checksum: [u8; 2],
4461    /// }
4462    ///
4463    /// #[derive(FromBytes, KnownLayout, Immutable)]
4464    /// #[repr(C)]
4465    /// struct Packet {
4466    ///     header: PacketHeader,
4467    ///     body: [[u8; 2]],
4468    /// }
4469    ///
4470    /// // These are more bytes than are needed to encode a `Packet`.
4471    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14][..];
4472    ///
4473    /// let (packet, suffix) = Packet::ref_from_prefix(bytes).unwrap();
4474    ///
4475    /// assert_eq!(packet.header.src_port, [0, 1]);
4476    /// assert_eq!(packet.header.dst_port, [2, 3]);
4477    /// assert_eq!(packet.header.length, [4, 5]);
4478    /// assert_eq!(packet.header.checksum, [6, 7]);
4479    /// assert_eq!(packet.body, [[8, 9], [10, 11], [12, 13]]);
4480    /// assert_eq!(suffix, &[14u8][..]);
4481    /// ```
4482    ///
4483    #[doc = codegen_section!(
4484        header = "h5",
4485        bench = "ref_from_prefix",
4486        format = "coco",
4487        arity = 3,
4488        [
4489            open
4490            @index 1
4491            @title "Sized"
4492            @variant "static_size"
4493        ],
4494        [
4495            @index 2
4496            @title "Unsized"
4497            @variant "dynamic_size"
4498        ],
4499        [
4500            @index 3
4501            @title "Dynamically Padded"
4502            @variant "dynamic_padding"
4503        ]
4504    )]
4505    #[must_use = "has no side effects"]
4506    #[cfg_attr(zerocopy_inline_always, inline(always))]
4507    #[cfg_attr(not(zerocopy_inline_always), inline)]
4508    fn ref_from_prefix(source: &[u8]) -> Result<(&Self, &[u8]), CastError<&[u8], Self>>
4509    where
4510        Self: KnownLayout + Immutable,
4511    {
4512        static_assert_dst_is_not_zst!(Self);
4513        ref_from_prefix_suffix(source, None, CastType::Prefix)
4514    }
4515
4516    /// Interprets the suffix of the given bytes as a `&Self`.
4517    ///
4518    /// This method computes the [largest possible size of `Self`][valid-size]
4519    /// that can fit in the trailing bytes of `source`, then attempts to return
4520    /// both a reference to those bytes interpreted as a `Self`, and a reference
4521    /// to the preceding bytes. If there are insufficient bytes, or if that
4522    /// suffix of `source` is not appropriately aligned, this returns `Err`. If
4523    /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the
4524    /// alignment error][size-error-from].
4525    ///
4526    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
4527    ///
4528    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
4529    /// [self-unaligned]: Unaligned
4530    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4531    /// [slice-dst]: KnownLayout#dynamically-sized-types
4532    ///
4533    /// # Compile-Time Assertions
4534    ///
4535    /// This method cannot yet be used on unsized types whose dynamically-sized
4536    /// component is zero-sized. See [`ref_from_suffix_with_elems`], which does
4537    /// support such types. Attempting to use this method on such types results
4538    /// in a compile-time assertion error; e.g.:
4539    ///
4540    /// ```compile_fail,E0080
4541    /// use zerocopy::*;
4542    /// # use zerocopy_derive::*;
4543    ///
4544    /// #[derive(FromBytes, Immutable, KnownLayout)]
4545    /// #[repr(C)]
4546    /// struct ZSTy {
4547    ///     leading_sized: u16,
4548    ///     trailing_dst: [()],
4549    /// }
4550    ///
4551    /// let _ = ZSTy::ref_from_suffix(0u16.as_bytes()); // âš  Compile Error!
4552    /// ```
4553    ///
4554    /// [`ref_from_suffix_with_elems`]: FromBytes::ref_from_suffix_with_elems
4555    ///
4556    /// # Examples
4557    ///
4558    /// ```
4559    /// use zerocopy::FromBytes;
4560    /// # use zerocopy_derive::*;
4561    ///
4562    /// #[derive(FromBytes, Immutable, KnownLayout)]
4563    /// #[repr(C)]
4564    /// struct PacketTrailer {
4565    ///     frame_check_sequence: [u8; 4],
4566    /// }
4567    ///
4568    /// // These are more bytes than are needed to encode a `PacketTrailer`.
4569    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
4570    ///
4571    /// let (prefix, trailer) = PacketTrailer::ref_from_suffix(bytes).unwrap();
4572    ///
4573    /// assert_eq!(prefix, &[0, 1, 2, 3, 4, 5][..]);
4574    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
4575    /// ```
4576    ///
4577    #[doc = codegen_section!(
4578        header = "h5",
4579        bench = "ref_from_suffix",
4580        format = "coco",
4581        arity = 3,
4582        [
4583            open
4584            @index 1
4585            @title "Sized"
4586            @variant "static_size"
4587        ],
4588        [
4589            @index 2
4590            @title "Unsized"
4591            @variant "dynamic_size"
4592        ],
4593        [
4594            @index 3
4595            @title "Dynamically Padded"
4596            @variant "dynamic_padding"
4597        ]
4598    )]
4599    #[must_use = "has no side effects"]
4600    #[cfg_attr(zerocopy_inline_always, inline(always))]
4601    #[cfg_attr(not(zerocopy_inline_always), inline)]
4602    fn ref_from_suffix(source: &[u8]) -> Result<(&[u8], &Self), CastError<&[u8], Self>>
4603    where
4604        Self: Immutable + KnownLayout,
4605    {
4606        static_assert_dst_is_not_zst!(Self);
4607        ref_from_prefix_suffix(source, None, CastType::Suffix).map(swap)
4608    }
4609
4610    /// Interprets the given `source` as a `&mut Self`.
4611    ///
4612    /// This method attempts to return a reference to `source` interpreted as a
4613    /// `Self`. If the length of `source` is not a [valid size of
4614    /// `Self`][valid-size], or if `source` is not appropriately aligned, this
4615    /// returns `Err`. If [`Self: Unaligned`][self-unaligned], you can
4616    /// [infallibly discard the alignment error][size-error-from].
4617    ///
4618    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
4619    ///
4620    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
4621    /// [self-unaligned]: Unaligned
4622    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4623    /// [slice-dst]: KnownLayout#dynamically-sized-types
4624    ///
4625    /// # Compile-Time Assertions
4626    ///
4627    /// This method cannot yet be used on unsized types whose dynamically-sized
4628    /// component is zero-sized. See [`mut_from_prefix_with_elems`], which does
4629    /// support such types. Attempting to use this method on such types results
4630    /// in a compile-time assertion error; e.g.:
4631    ///
4632    /// ```compile_fail,E0080
4633    /// use zerocopy::*;
4634    /// # use zerocopy_derive::*;
4635    ///
4636    /// #[derive(FromBytes, Immutable, IntoBytes, KnownLayout)]
4637    /// #[repr(C, packed)]
4638    /// struct ZSTy {
4639    ///     leading_sized: [u8; 2],
4640    ///     trailing_dst: [()],
4641    /// }
4642    ///
4643    /// let mut source = [85, 85];
4644    /// let _ = ZSTy::mut_from_bytes(&mut source[..]); // âš  Compile Error!
4645    /// ```
4646    ///
4647    /// [`mut_from_prefix_with_elems`]: FromBytes::mut_from_prefix_with_elems
4648    ///
4649    /// # Examples
4650    ///
4651    /// ```
4652    /// use zerocopy::FromBytes;
4653    /// # use zerocopy_derive::*;
4654    ///
4655    /// #[derive(FromBytes, IntoBytes, KnownLayout, Immutable)]
4656    /// #[repr(C)]
4657    /// struct PacketHeader {
4658    ///     src_port: [u8; 2],
4659    ///     dst_port: [u8; 2],
4660    ///     length: [u8; 2],
4661    ///     checksum: [u8; 2],
4662    /// }
4663    ///
4664    /// // These bytes encode a `PacketHeader`.
4665    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
4666    ///
4667    /// let header = PacketHeader::mut_from_bytes(bytes).unwrap();
4668    ///
4669    /// assert_eq!(header.src_port, [0, 1]);
4670    /// assert_eq!(header.dst_port, [2, 3]);
4671    /// assert_eq!(header.length, [4, 5]);
4672    /// assert_eq!(header.checksum, [6, 7]);
4673    ///
4674    /// header.checksum = [0, 0];
4675    ///
4676    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0]);
4677    ///
4678    /// ```
4679    ///
4680    #[doc = codegen_header!("h5", "mut_from_bytes")]
4681    ///
4682    /// See [`FromBytes::ref_from_bytes`](#method.ref_from_bytes.codegen).
4683    #[must_use = "has no side effects"]
4684    #[cfg_attr(zerocopy_inline_always, inline(always))]
4685    #[cfg_attr(not(zerocopy_inline_always), inline)]
4686    fn mut_from_bytes(source: &mut [u8]) -> Result<&mut Self, CastError<&mut [u8], Self>>
4687    where
4688        Self: IntoBytes + KnownLayout,
4689    {
4690        static_assert_dst_is_not_zst!(Self);
4691        match Ptr::from_mut(source).try_cast_into_no_leftover::<_, BecauseExclusive>(None) {
4692            Ok(ptr) => Ok(ptr.recall_validity::<_, (_, (_, _))>().as_mut()),
4693            Err(err) => Err(err.map_src(|src| src.as_mut())),
4694        }
4695    }
4696
4697    /// Interprets the prefix of the given `source` as a `&mut Self` without
4698    /// copying.
4699    ///
4700    /// This method computes the [largest possible size of `Self`][valid-size]
4701    /// that can fit in the leading bytes of `source`, then attempts to return
4702    /// both a reference to those bytes interpreted as a `Self`, and a reference
4703    /// to the remaining bytes. If there are insufficient bytes, or if `source`
4704    /// is not appropriately aligned, this returns `Err`. If [`Self:
4705    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
4706    /// error][size-error-from].
4707    ///
4708    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
4709    ///
4710    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
4711    /// [self-unaligned]: Unaligned
4712    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4713    /// [slice-dst]: KnownLayout#dynamically-sized-types
4714    ///
4715    /// # Compile-Time Assertions
4716    ///
4717    /// This method cannot yet be used on unsized types whose dynamically-sized
4718    /// component is zero-sized. See [`mut_from_suffix_with_elems`], which does
4719    /// support such types. Attempting to use this method on such types results
4720    /// in a compile-time assertion error; e.g.:
4721    ///
4722    /// ```compile_fail,E0080
4723    /// use zerocopy::*;
4724    /// # use zerocopy_derive::*;
4725    ///
4726    /// #[derive(FromBytes, Immutable, IntoBytes, KnownLayout)]
4727    /// #[repr(C, packed)]
4728    /// struct ZSTy {
4729    ///     leading_sized: [u8; 2],
4730    ///     trailing_dst: [()],
4731    /// }
4732    ///
4733    /// let mut source = [85, 85];
4734    /// let _ = ZSTy::mut_from_prefix(&mut source[..]); // âš  Compile Error!
4735    /// ```
4736    ///
4737    /// [`mut_from_suffix_with_elems`]: FromBytes::mut_from_suffix_with_elems
4738    ///
4739    /// # Examples
4740    ///
4741    /// ```
4742    /// use zerocopy::FromBytes;
4743    /// # use zerocopy_derive::*;
4744    ///
4745    /// #[derive(FromBytes, IntoBytes, KnownLayout, Immutable)]
4746    /// #[repr(C)]
4747    /// struct PacketHeader {
4748    ///     src_port: [u8; 2],
4749    ///     dst_port: [u8; 2],
4750    ///     length: [u8; 2],
4751    ///     checksum: [u8; 2],
4752    /// }
4753    ///
4754    /// // These are more bytes than are needed to encode a `PacketHeader`.
4755    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
4756    ///
4757    /// let (header, body) = PacketHeader::mut_from_prefix(bytes).unwrap();
4758    ///
4759    /// assert_eq!(header.src_port, [0, 1]);
4760    /// assert_eq!(header.dst_port, [2, 3]);
4761    /// assert_eq!(header.length, [4, 5]);
4762    /// assert_eq!(header.checksum, [6, 7]);
4763    /// assert_eq!(body, &[8, 9][..]);
4764    ///
4765    /// header.checksum = [0, 0];
4766    /// body.fill(1);
4767    ///
4768    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 1, 1]);
4769    /// ```
4770    ///
4771    #[doc = codegen_header!("h5", "mut_from_prefix")]
4772    ///
4773    /// See [`FromBytes::ref_from_prefix`](#method.ref_from_prefix.codegen).
4774    #[must_use = "has no side effects"]
4775    #[cfg_attr(zerocopy_inline_always, inline(always))]
4776    #[cfg_attr(not(zerocopy_inline_always), inline)]
4777    fn mut_from_prefix(
4778        source: &mut [u8],
4779    ) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>>
4780    where
4781        Self: IntoBytes + KnownLayout,
4782    {
4783        static_assert_dst_is_not_zst!(Self);
4784        mut_from_prefix_suffix(source, None, CastType::Prefix)
4785    }
4786
4787    /// Interprets the suffix of the given `source` as a `&mut Self` without
4788    /// copying.
4789    ///
4790    /// This method computes the [largest possible size of `Self`][valid-size]
4791    /// that can fit in the trailing bytes of `source`, then attempts to return
4792    /// both a reference to those bytes interpreted as a `Self`, and a reference
4793    /// to the preceding bytes. If there are insufficient bytes, or if that
4794    /// suffix of `source` is not appropriately aligned, this returns `Err`. If
4795    /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the
4796    /// alignment error][size-error-from].
4797    ///
4798    /// `Self` may be a sized type, a slice, or a [slice DST][slice-dst].
4799    ///
4800    /// [valid-size]: crate::KnownLayout#what-is-a-valid-size
4801    /// [self-unaligned]: Unaligned
4802    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4803    /// [slice-dst]: KnownLayout#dynamically-sized-types
4804    ///
4805    /// # Compile-Time Assertions
4806    ///
4807    /// This method cannot yet be used on unsized types whose dynamically-sized
4808    /// component is zero-sized. Attempting to use this method on such types
4809    /// results in a compile-time assertion error; e.g.:
4810    ///
4811    /// ```compile_fail,E0080
4812    /// use zerocopy::*;
4813    /// # use zerocopy_derive::*;
4814    ///
4815    /// #[derive(FromBytes, Immutable, IntoBytes, KnownLayout)]
4816    /// #[repr(C, packed)]
4817    /// struct ZSTy {
4818    ///     leading_sized: [u8; 2],
4819    ///     trailing_dst: [()],
4820    /// }
4821    ///
4822    /// let mut source = [85, 85];
4823    /// let _ = ZSTy::mut_from_suffix(&mut source[..]); // âš  Compile Error!
4824    /// ```
4825    ///
4826    /// # Examples
4827    ///
4828    /// ```
4829    /// use zerocopy::FromBytes;
4830    /// # use zerocopy_derive::*;
4831    ///
4832    /// #[derive(FromBytes, IntoBytes, KnownLayout, Immutable)]
4833    /// #[repr(C)]
4834    /// struct PacketTrailer {
4835    ///     frame_check_sequence: [u8; 4],
4836    /// }
4837    ///
4838    /// // These are more bytes than are needed to encode a `PacketTrailer`.
4839    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
4840    ///
4841    /// let (prefix, trailer) = PacketTrailer::mut_from_suffix(bytes).unwrap();
4842    ///
4843    /// assert_eq!(prefix, &[0u8, 1, 2, 3, 4, 5][..]);
4844    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
4845    ///
4846    /// prefix.fill(0);
4847    /// trailer.frame_check_sequence.fill(1);
4848    ///
4849    /// assert_eq!(bytes, [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]);
4850    /// ```
4851    ///
4852    #[doc = codegen_header!("h5", "mut_from_suffix")]
4853    ///
4854    /// See [`FromBytes::ref_from_suffix`](#method.ref_from_suffix.codegen).
4855    #[must_use = "has no side effects"]
4856    #[cfg_attr(zerocopy_inline_always, inline(always))]
4857    #[cfg_attr(not(zerocopy_inline_always), inline)]
4858    fn mut_from_suffix(
4859        source: &mut [u8],
4860    ) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>>
4861    where
4862        Self: IntoBytes + KnownLayout,
4863    {
4864        static_assert_dst_is_not_zst!(Self);
4865        mut_from_prefix_suffix(source, None, CastType::Suffix).map(swap)
4866    }
4867
4868    /// Interprets the given `source` as a `&Self` with a DST length equal to
4869    /// `count`.
4870    ///
4871    /// This method attempts to return a reference to `source` interpreted as a
4872    /// `Self` with `count` trailing elements. If the length of `source` is not
4873    /// equal to the size of `Self` with `count` elements, or if `source` is not
4874    /// appropriately aligned, this returns `Err`. If [`Self:
4875    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
4876    /// error][size-error-from].
4877    ///
4878    /// [self-unaligned]: Unaligned
4879    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4880    ///
4881    /// # Examples
4882    ///
4883    /// ```
4884    /// use zerocopy::FromBytes;
4885    /// # use zerocopy_derive::*;
4886    ///
4887    /// # #[derive(Debug, PartialEq, Eq)]
4888    /// #[derive(FromBytes, Immutable)]
4889    /// #[repr(C)]
4890    /// struct Pixel {
4891    ///     r: u8,
4892    ///     g: u8,
4893    ///     b: u8,
4894    ///     a: u8,
4895    /// }
4896    ///
4897    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7][..];
4898    ///
4899    /// let pixels = <[Pixel]>::ref_from_bytes_with_elems(bytes, 2).unwrap();
4900    ///
4901    /// assert_eq!(pixels, &[
4902    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
4903    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
4904    /// ]);
4905    ///
4906    /// ```
4907    ///
4908    /// Since an explicit `count` is provided, this method supports types with
4909    /// zero-sized trailing slice elements. Methods such as [`ref_from_bytes`]
4910    /// which do not take an explicit count do not support such types.
4911    ///
4912    /// ```
4913    /// use zerocopy::*;
4914    /// # use zerocopy_derive::*;
4915    ///
4916    /// #[derive(FromBytes, Immutable, KnownLayout)]
4917    /// #[repr(C)]
4918    /// struct ZSTy {
4919    ///     leading_sized: [u8; 2],
4920    ///     trailing_dst: [()],
4921    /// }
4922    ///
4923    /// let src = &[85, 85][..];
4924    /// let zsty = ZSTy::ref_from_bytes_with_elems(src, 42).unwrap();
4925    /// assert_eq!(zsty.trailing_dst.len(), 42);
4926    /// ```
4927    ///
4928    /// [`ref_from_bytes`]: FromBytes::ref_from_bytes
4929    ///
4930    #[doc = codegen_section!(
4931        header = "h5",
4932        bench = "ref_from_bytes_with_elems",
4933        format = "coco",
4934        arity = 2,
4935        [
4936            open
4937            @index 1
4938            @title "Unsized"
4939            @variant "dynamic_size"
4940        ],
4941        [
4942            @index 2
4943            @title "Dynamically Padded"
4944            @variant "dynamic_padding"
4945        ]
4946    )]
4947    #[must_use = "has no side effects"]
4948    #[cfg_attr(zerocopy_inline_always, inline(always))]
4949    #[cfg_attr(not(zerocopy_inline_always), inline)]
4950    fn ref_from_bytes_with_elems(
4951        source: &[u8],
4952        count: usize,
4953    ) -> Result<&Self, CastError<&[u8], Self>>
4954    where
4955        Self: KnownLayout<PointerMetadata = usize> + Immutable,
4956    {
4957        let source = Ptr::from_ref(source);
4958        let maybe_slf = source.try_cast_into_no_leftover::<_, BecauseImmutable>(Some(count));
4959        match maybe_slf {
4960            Ok(slf) => Ok(slf.recall_validity().as_ref()),
4961            Err(err) => Err(err.map_src(|s| s.as_ref())),
4962        }
4963    }
4964
4965    /// Interprets the prefix of the given `source` as a DST `&Self` with length
4966    /// equal to `count`.
4967    ///
4968    /// This method attempts to return a reference to the prefix of `source`
4969    /// interpreted as a `Self` with `count` trailing elements, and a reference
4970    /// to the remaining bytes. If there are insufficient bytes, or if `source`
4971    /// is not appropriately aligned, this returns `Err`. If [`Self:
4972    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
4973    /// error][size-error-from].
4974    ///
4975    /// [self-unaligned]: Unaligned
4976    /// [size-error-from]: error/struct.SizeError.html#method.from-1
4977    ///
4978    /// # Examples
4979    ///
4980    /// ```
4981    /// use zerocopy::FromBytes;
4982    /// # use zerocopy_derive::*;
4983    ///
4984    /// # #[derive(Debug, PartialEq, Eq)]
4985    /// #[derive(FromBytes, Immutable)]
4986    /// #[repr(C)]
4987    /// struct Pixel {
4988    ///     r: u8,
4989    ///     g: u8,
4990    ///     b: u8,
4991    ///     a: u8,
4992    /// }
4993    ///
4994    /// // These are more bytes than are needed to encode two `Pixel`s.
4995    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
4996    ///
4997    /// let (pixels, suffix) = <[Pixel]>::ref_from_prefix_with_elems(bytes, 2).unwrap();
4998    ///
4999    /// assert_eq!(pixels, &[
5000    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
5001    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
5002    /// ]);
5003    ///
5004    /// assert_eq!(suffix, &[8, 9]);
5005    /// ```
5006    ///
5007    /// Since an explicit `count` is provided, this method supports types with
5008    /// zero-sized trailing slice elements. Methods such as [`ref_from_prefix`]
5009    /// which do not take an explicit count do not support such types.
5010    ///
5011    /// ```
5012    /// use zerocopy::*;
5013    /// # use zerocopy_derive::*;
5014    ///
5015    /// #[derive(FromBytes, Immutable, KnownLayout)]
5016    /// #[repr(C)]
5017    /// struct ZSTy {
5018    ///     leading_sized: [u8; 2],
5019    ///     trailing_dst: [()],
5020    /// }
5021    ///
5022    /// let src = &[85, 85][..];
5023    /// let (zsty, _) = ZSTy::ref_from_prefix_with_elems(src, 42).unwrap();
5024    /// assert_eq!(zsty.trailing_dst.len(), 42);
5025    /// ```
5026    ///
5027    /// [`ref_from_prefix`]: FromBytes::ref_from_prefix
5028    ///
5029    #[doc = codegen_section!(
5030        header = "h5",
5031        bench = "ref_from_prefix_with_elems",
5032        format = "coco",
5033        arity = 2,
5034        [
5035            open
5036            @index 1
5037            @title "Unsized"
5038            @variant "dynamic_size"
5039        ],
5040        [
5041            @index 2
5042            @title "Dynamically Padded"
5043            @variant "dynamic_padding"
5044        ]
5045    )]
5046    #[must_use = "has no side effects"]
5047    #[cfg_attr(zerocopy_inline_always, inline(always))]
5048    #[cfg_attr(not(zerocopy_inline_always), inline)]
5049    fn ref_from_prefix_with_elems(
5050        source: &[u8],
5051        count: usize,
5052    ) -> Result<(&Self, &[u8]), CastError<&[u8], Self>>
5053    where
5054        Self: KnownLayout<PointerMetadata = usize> + Immutable,
5055    {
5056        ref_from_prefix_suffix(source, Some(count), CastType::Prefix)
5057    }
5058
5059    /// Interprets the suffix of the given `source` as a DST `&Self` with length
5060    /// equal to `count`.
5061    ///
5062    /// This method attempts to return a reference to the suffix of `source`
5063    /// interpreted as a `Self` with `count` trailing elements, and a reference
5064    /// to the preceding bytes. If there are insufficient bytes, or if that
5065    /// suffix of `source` is not appropriately aligned, this returns `Err`. If
5066    /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the
5067    /// alignment error][size-error-from].
5068    ///
5069    /// [self-unaligned]: Unaligned
5070    /// [size-error-from]: error/struct.SizeError.html#method.from-1
5071    ///
5072    /// # Examples
5073    ///
5074    /// ```
5075    /// use zerocopy::FromBytes;
5076    /// # use zerocopy_derive::*;
5077    ///
5078    /// # #[derive(Debug, PartialEq, Eq)]
5079    /// #[derive(FromBytes, Immutable)]
5080    /// #[repr(C)]
5081    /// struct Pixel {
5082    ///     r: u8,
5083    ///     g: u8,
5084    ///     b: u8,
5085    ///     a: u8,
5086    /// }
5087    ///
5088    /// // These are more bytes than are needed to encode two `Pixel`s.
5089    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
5090    ///
5091    /// let (prefix, pixels) = <[Pixel]>::ref_from_suffix_with_elems(bytes, 2).unwrap();
5092    ///
5093    /// assert_eq!(prefix, &[0, 1]);
5094    ///
5095    /// assert_eq!(pixels, &[
5096    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
5097    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
5098    /// ]);
5099    /// ```
5100    ///
5101    /// Since an explicit `count` is provided, this method supports types with
5102    /// zero-sized trailing slice elements. Methods such as [`ref_from_suffix`]
5103    /// which do not take an explicit count do not support such types.
5104    ///
5105    /// ```
5106    /// use zerocopy::*;
5107    /// # use zerocopy_derive::*;
5108    ///
5109    /// #[derive(FromBytes, Immutable, KnownLayout)]
5110    /// #[repr(C)]
5111    /// struct ZSTy {
5112    ///     leading_sized: [u8; 2],
5113    ///     trailing_dst: [()],
5114    /// }
5115    ///
5116    /// let src = &[85, 85][..];
5117    /// let (_, zsty) = ZSTy::ref_from_suffix_with_elems(src, 42).unwrap();
5118    /// assert_eq!(zsty.trailing_dst.len(), 42);
5119    /// ```
5120    ///
5121    /// [`ref_from_suffix`]: FromBytes::ref_from_suffix
5122    ///
5123    #[doc = codegen_section!(
5124        header = "h5",
5125        bench = "ref_from_suffix_with_elems",
5126        format = "coco",
5127        arity = 2,
5128        [
5129            open
5130            @index 1
5131            @title "Unsized"
5132            @variant "dynamic_size"
5133        ],
5134        [
5135            @index 2
5136            @title "Dynamically Padded"
5137            @variant "dynamic_padding"
5138        ]
5139    )]
5140    #[must_use = "has no side effects"]
5141    #[cfg_attr(zerocopy_inline_always, inline(always))]
5142    #[cfg_attr(not(zerocopy_inline_always), inline)]
5143    fn ref_from_suffix_with_elems(
5144        source: &[u8],
5145        count: usize,
5146    ) -> Result<(&[u8], &Self), CastError<&[u8], Self>>
5147    where
5148        Self: KnownLayout<PointerMetadata = usize> + Immutable,
5149    {
5150        ref_from_prefix_suffix(source, Some(count), CastType::Suffix).map(swap)
5151    }
5152
5153    /// Interprets the given `source` as a `&mut Self` with a DST length equal
5154    /// to `count`.
5155    ///
5156    /// This method attempts to return a reference to `source` interpreted as a
5157    /// `Self` with `count` trailing elements. If the length of `source` is not
5158    /// equal to the size of `Self` with `count` elements, or if `source` is not
5159    /// appropriately aligned, this returns `Err`. If [`Self:
5160    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
5161    /// error][size-error-from].
5162    ///
5163    /// [self-unaligned]: Unaligned
5164    /// [size-error-from]: error/struct.SizeError.html#method.from-1
5165    ///
5166    /// # Examples
5167    ///
5168    /// ```
5169    /// use zerocopy::FromBytes;
5170    /// # use zerocopy_derive::*;
5171    ///
5172    /// # #[derive(Debug, PartialEq, Eq)]
5173    /// #[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]
5174    /// #[repr(C)]
5175    /// struct Pixel {
5176    ///     r: u8,
5177    ///     g: u8,
5178    ///     b: u8,
5179    ///     a: u8,
5180    /// }
5181    ///
5182    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
5183    ///
5184    /// let pixels = <[Pixel]>::mut_from_bytes_with_elems(bytes, 2).unwrap();
5185    ///
5186    /// assert_eq!(pixels, &[
5187    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
5188    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
5189    /// ]);
5190    ///
5191    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
5192    ///
5193    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0]);
5194    /// ```
5195    ///
5196    /// Since an explicit `count` is provided, this method supports types with
5197    /// zero-sized trailing slice elements. Methods such as [`mut_from_bytes`]
5198    /// which do not take an explicit count do not support such types.
5199    ///
5200    /// ```
5201    /// use zerocopy::*;
5202    /// # use zerocopy_derive::*;
5203    ///
5204    /// #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
5205    /// #[repr(C, packed)]
5206    /// struct ZSTy {
5207    ///     leading_sized: [u8; 2],
5208    ///     trailing_dst: [()],
5209    /// }
5210    ///
5211    /// let src = &mut [85, 85][..];
5212    /// let zsty = ZSTy::mut_from_bytes_with_elems(src, 42).unwrap();
5213    /// assert_eq!(zsty.trailing_dst.len(), 42);
5214    /// ```
5215    ///
5216    /// [`mut_from_bytes`]: FromBytes::mut_from_bytes
5217    ///
5218    #[doc = codegen_header!("h5", "mut_from_bytes_with_elems")]
5219    ///
5220    /// See [`TryFromBytes::ref_from_bytes_with_elems`](#method.ref_from_bytes_with_elems.codegen).
5221    #[must_use = "has no side effects"]
5222    #[cfg_attr(zerocopy_inline_always, inline(always))]
5223    #[cfg_attr(not(zerocopy_inline_always), inline)]
5224    fn mut_from_bytes_with_elems(
5225        source: &mut [u8],
5226        count: usize,
5227    ) -> Result<&mut Self, CastError<&mut [u8], Self>>
5228    where
5229        Self: IntoBytes + KnownLayout<PointerMetadata = usize> + Immutable,
5230    {
5231        let source = Ptr::from_mut(source);
5232        let maybe_slf = source.try_cast_into_no_leftover::<_, BecauseImmutable>(Some(count));
5233        match maybe_slf {
5234            Ok(slf) => Ok(slf.recall_validity::<_, (_, (_, BecauseExclusive))>().as_mut()),
5235            Err(err) => Err(err.map_src(|s| s.as_mut())),
5236        }
5237    }
5238
5239    /// Interprets the prefix of the given `source` as a `&mut Self` with DST
5240    /// length equal to `count`.
5241    ///
5242    /// This method attempts to return a reference to the prefix of `source`
5243    /// interpreted as a `Self` with `count` trailing elements, and a reference
5244    /// to the preceding bytes. If there are insufficient bytes, or if `source`
5245    /// is not appropriately aligned, this returns `Err`. If [`Self:
5246    /// Unaligned`][self-unaligned], you can [infallibly discard the alignment
5247    /// error][size-error-from].
5248    ///
5249    /// [self-unaligned]: Unaligned
5250    /// [size-error-from]: error/struct.SizeError.html#method.from-1
5251    ///
5252    /// # Examples
5253    ///
5254    /// ```
5255    /// use zerocopy::FromBytes;
5256    /// # use zerocopy_derive::*;
5257    ///
5258    /// # #[derive(Debug, PartialEq, Eq)]
5259    /// #[derive(KnownLayout, FromBytes, IntoBytes, Immutable)]
5260    /// #[repr(C)]
5261    /// struct Pixel {
5262    ///     r: u8,
5263    ///     g: u8,
5264    ///     b: u8,
5265    ///     a: u8,
5266    /// }
5267    ///
5268    /// // These are more bytes than are needed to encode two `Pixel`s.
5269    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
5270    ///
5271    /// let (pixels, suffix) = <[Pixel]>::mut_from_prefix_with_elems(bytes, 2).unwrap();
5272    ///
5273    /// assert_eq!(pixels, &[
5274    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
5275    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
5276    /// ]);
5277    ///
5278    /// assert_eq!(suffix, &[8, 9]);
5279    ///
5280    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
5281    /// suffix.fill(1);
5282    ///
5283    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0, 1, 1]);
5284    /// ```
5285    ///
5286    /// Since an explicit `count` is provided, this method supports types with
5287    /// zero-sized trailing slice elements. Methods such as [`mut_from_prefix`]
5288    /// which do not take an explicit count do not support such types.
5289    ///
5290    /// ```
5291    /// use zerocopy::*;
5292    /// # use zerocopy_derive::*;
5293    ///
5294    /// #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
5295    /// #[repr(C, packed)]
5296    /// struct ZSTy {
5297    ///     leading_sized: [u8; 2],
5298    ///     trailing_dst: [()],
5299    /// }
5300    ///
5301    /// let src = &mut [85, 85][..];
5302    /// let (zsty, _) = ZSTy::mut_from_prefix_with_elems(src, 42).unwrap();
5303    /// assert_eq!(zsty.trailing_dst.len(), 42);
5304    /// ```
5305    ///
5306    /// [`mut_from_prefix`]: FromBytes::mut_from_prefix
5307    ///
5308    #[doc = codegen_header!("h5", "mut_from_prefix_with_elems")]
5309    ///
5310    /// See [`TryFromBytes::ref_from_prefix_with_elems`](#method.ref_from_prefix_with_elems.codegen).
5311    #[must_use = "has no side effects"]
5312    #[cfg_attr(zerocopy_inline_always, inline(always))]
5313    #[cfg_attr(not(zerocopy_inline_always), inline)]
5314    fn mut_from_prefix_with_elems(
5315        source: &mut [u8],
5316        count: usize,
5317    ) -> Result<(&mut Self, &mut [u8]), CastError<&mut [u8], Self>>
5318    where
5319        Self: IntoBytes + KnownLayout<PointerMetadata = usize>,
5320    {
5321        mut_from_prefix_suffix(source, Some(count), CastType::Prefix)
5322    }
5323
5324    /// Interprets the suffix of the given `source` as a `&mut Self` with DST
5325    /// length equal to `count`.
5326    ///
5327    /// This method attempts to return a reference to the suffix of `source`
5328    /// interpreted as a `Self` with `count` trailing elements, and a reference
5329    /// to the remaining bytes. If there are insufficient bytes, or if that
5330    /// suffix of `source` is not appropriately aligned, this returns `Err`. If
5331    /// [`Self: Unaligned`][self-unaligned], you can [infallibly discard the
5332    /// alignment error][size-error-from].
5333    ///
5334    /// [self-unaligned]: Unaligned
5335    /// [size-error-from]: error/struct.SizeError.html#method.from-1
5336    ///
5337    /// # Examples
5338    ///
5339    /// ```
5340    /// use zerocopy::FromBytes;
5341    /// # use zerocopy_derive::*;
5342    ///
5343    /// # #[derive(Debug, PartialEq, Eq)]
5344    /// #[derive(FromBytes, IntoBytes, Immutable)]
5345    /// #[repr(C)]
5346    /// struct Pixel {
5347    ///     r: u8,
5348    ///     g: u8,
5349    ///     b: u8,
5350    ///     a: u8,
5351    /// }
5352    ///
5353    /// // These are more bytes than are needed to encode two `Pixel`s.
5354    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
5355    ///
5356    /// let (prefix, pixels) = <[Pixel]>::mut_from_suffix_with_elems(bytes, 2).unwrap();
5357    ///
5358    /// assert_eq!(prefix, &[0, 1]);
5359    ///
5360    /// assert_eq!(pixels, &[
5361    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
5362    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
5363    /// ]);
5364    ///
5365    /// prefix.fill(9);
5366    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
5367    ///
5368    /// assert_eq!(bytes, [9, 9, 2, 3, 4, 5, 0, 0, 0, 0]);
5369    /// ```
5370    ///
5371    /// Since an explicit `count` is provided, this method supports types with
5372    /// zero-sized trailing slice elements. Methods such as [`mut_from_suffix`]
5373    /// which do not take an explicit count do not support such types.
5374    ///
5375    /// ```
5376    /// use zerocopy::*;
5377    /// # use zerocopy_derive::*;
5378    ///
5379    /// #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
5380    /// #[repr(C, packed)]
5381    /// struct ZSTy {
5382    ///     leading_sized: [u8; 2],
5383    ///     trailing_dst: [()],
5384    /// }
5385    ///
5386    /// let src = &mut [85, 85][..];
5387    /// let (_, zsty) = ZSTy::mut_from_suffix_with_elems(src, 42).unwrap();
5388    /// assert_eq!(zsty.trailing_dst.len(), 42);
5389    /// ```
5390    ///
5391    /// [`mut_from_suffix`]: FromBytes::mut_from_suffix
5392    ///
5393    #[doc = codegen_header!("h5", "mut_from_suffix_with_elems")]
5394    ///
5395    /// See [`TryFromBytes::ref_from_suffix_with_elems`](#method.ref_from_suffix_with_elems.codegen).
5396    #[must_use = "has no side effects"]
5397    #[cfg_attr(zerocopy_inline_always, inline(always))]
5398    #[cfg_attr(not(zerocopy_inline_always), inline)]
5399    fn mut_from_suffix_with_elems(
5400        source: &mut [u8],
5401        count: usize,
5402    ) -> Result<(&mut [u8], &mut Self), CastError<&mut [u8], Self>>
5403    where
5404        Self: IntoBytes + KnownLayout<PointerMetadata = usize>,
5405    {
5406        mut_from_prefix_suffix(source, Some(count), CastType::Suffix).map(swap)
5407    }
5408
5409    /// Reads a copy of `Self` from the given `source`.
5410    ///
5411    /// If `source.len() != size_of::<Self>()`, `read_from_bytes` returns `Err`.
5412    ///
5413    /// # Examples
5414    ///
5415    /// ```
5416    /// use zerocopy::FromBytes;
5417    /// # use zerocopy_derive::*;
5418    ///
5419    /// #[derive(FromBytes)]
5420    /// #[repr(C)]
5421    /// struct PacketHeader {
5422    ///     src_port: [u8; 2],
5423    ///     dst_port: [u8; 2],
5424    ///     length: [u8; 2],
5425    ///     checksum: [u8; 2],
5426    /// }
5427    ///
5428    /// // These bytes encode a `PacketHeader`.
5429    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7][..];
5430    ///
5431    /// let header = PacketHeader::read_from_bytes(bytes).unwrap();
5432    ///
5433    /// assert_eq!(header.src_port, [0, 1]);
5434    /// assert_eq!(header.dst_port, [2, 3]);
5435    /// assert_eq!(header.length, [4, 5]);
5436    /// assert_eq!(header.checksum, [6, 7]);
5437    /// ```
5438    ///
5439    #[doc = codegen_section!(
5440        header = "h5",
5441        bench = "read_from_bytes",
5442        format = "coco_static_size",
5443    )]
5444    #[must_use = "has no side effects"]
5445    #[cfg_attr(zerocopy_inline_always, inline(always))]
5446    #[cfg_attr(not(zerocopy_inline_always), inline)]
5447    fn read_from_bytes(source: &[u8]) -> Result<Self, SizeError<&[u8], Self>>
5448    where
5449        Self: Sized,
5450    {
5451        match Ref::<_, Unalign<Self>>::sized_from(source) {
5452            Ok(r) => Ok(Ref::read(&r).into_inner()),
5453            Err(CastError::Size(e)) => Err(e.with_dst()),
5454            Err(CastError::Alignment(_)) => {
5455                // SAFETY: `Unalign<Self>` is trivially aligned, so
5456                // `Ref::sized_from` cannot fail due to unmet alignment
5457                // requirements.
5458                unsafe { core::hint::unreachable_unchecked() }
5459            }
5460            Err(CastError::Validity(i)) => match i {},
5461        }
5462    }
5463
5464    /// Reads a copy of `Self` from the prefix of the given `source`.
5465    ///
5466    /// This attempts to read a `Self` from the first `size_of::<Self>()` bytes
5467    /// of `source`, returning that `Self` and any remaining bytes. If
5468    /// `source.len() < size_of::<Self>()`, it returns `Err`.
5469    ///
5470    /// # Examples
5471    ///
5472    /// ```
5473    /// use zerocopy::FromBytes;
5474    /// # use zerocopy_derive::*;
5475    ///
5476    /// #[derive(FromBytes)]
5477    /// #[repr(C)]
5478    /// struct PacketHeader {
5479    ///     src_port: [u8; 2],
5480    ///     dst_port: [u8; 2],
5481    ///     length: [u8; 2],
5482    ///     checksum: [u8; 2],
5483    /// }
5484    ///
5485    /// // These are more bytes than are needed to encode a `PacketHeader`.
5486    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
5487    ///
5488    /// let (header, body) = PacketHeader::read_from_prefix(bytes).unwrap();
5489    ///
5490    /// assert_eq!(header.src_port, [0, 1]);
5491    /// assert_eq!(header.dst_port, [2, 3]);
5492    /// assert_eq!(header.length, [4, 5]);
5493    /// assert_eq!(header.checksum, [6, 7]);
5494    /// assert_eq!(body, [8, 9]);
5495    /// ```
5496    ///
5497    #[doc = codegen_section!(
5498        header = "h5",
5499        bench = "read_from_prefix",
5500        format = "coco_static_size",
5501    )]
5502    #[must_use = "has no side effects"]
5503    #[cfg_attr(zerocopy_inline_always, inline(always))]
5504    #[cfg_attr(not(zerocopy_inline_always), inline)]
5505    fn read_from_prefix(source: &[u8]) -> Result<(Self, &[u8]), SizeError<&[u8], Self>>
5506    where
5507        Self: Sized,
5508    {
5509        match Ref::<_, Unalign<Self>>::sized_from_prefix(source) {
5510            Ok((r, suffix)) => Ok((Ref::read(&r).into_inner(), suffix)),
5511            Err(CastError::Size(e)) => Err(e.with_dst()),
5512            Err(CastError::Alignment(_)) => {
5513                // SAFETY: `Unalign<Self>` is trivially aligned, so
5514                // `Ref::sized_from_prefix` cannot fail due to unmet alignment
5515                // requirements.
5516                unsafe { core::hint::unreachable_unchecked() }
5517            }
5518            Err(CastError::Validity(i)) => match i {},
5519        }
5520    }
5521
5522    /// Reads a copy of `Self` from the suffix of the given `source`.
5523    ///
5524    /// This attempts to read a `Self` from the last `size_of::<Self>()` bytes
5525    /// of `source`, returning that `Self` and any preceding bytes. If
5526    /// `source.len() < size_of::<Self>()`, it returns `Err`.
5527    ///
5528    /// # Examples
5529    ///
5530    /// ```
5531    /// use zerocopy::FromBytes;
5532    /// # use zerocopy_derive::*;
5533    ///
5534    /// #[derive(FromBytes)]
5535    /// #[repr(C)]
5536    /// struct PacketTrailer {
5537    ///     frame_check_sequence: [u8; 4],
5538    /// }
5539    ///
5540    /// // These are more bytes than are needed to encode a `PacketTrailer`.
5541    /// let bytes = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
5542    ///
5543    /// let (prefix, trailer) = PacketTrailer::read_from_suffix(bytes).unwrap();
5544    ///
5545    /// assert_eq!(prefix, [0, 1, 2, 3, 4, 5]);
5546    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
5547    /// ```
5548    ///
5549    #[doc = codegen_section!(
5550        header = "h5",
5551        bench = "read_from_suffix",
5552        format = "coco_static_size",
5553    )]
5554    #[must_use = "has no side effects"]
5555    #[cfg_attr(zerocopy_inline_always, inline(always))]
5556    #[cfg_attr(not(zerocopy_inline_always), inline)]
5557    fn read_from_suffix(source: &[u8]) -> Result<(&[u8], Self), SizeError<&[u8], Self>>
5558    where
5559        Self: Sized,
5560    {
5561        match Ref::<_, Unalign<Self>>::sized_from_suffix(source) {
5562            Ok((prefix, r)) => Ok((prefix, Ref::read(&r).into_inner())),
5563            Err(CastError::Size(e)) => Err(e.with_dst()),
5564            Err(CastError::Alignment(_)) => {
5565                // SAFETY: `Unalign<Self>` is trivially aligned, so
5566                // `Ref::sized_from_suffix` cannot fail due to unmet alignment
5567                // requirements.
5568                unsafe { core::hint::unreachable_unchecked() }
5569            }
5570            Err(CastError::Validity(i)) => match i {},
5571        }
5572    }
5573
5574    /// Reads a copy of `self` from an `io::Read`.
5575    ///
5576    /// This is useful for interfacing with operating system byte sinks (files,
5577    /// sockets, etc.).
5578    ///
5579    /// # Examples
5580    ///
5581    /// ```no_run
5582    /// use zerocopy::{byteorder::big_endian::*, FromBytes};
5583    /// use std::fs::File;
5584    /// # use zerocopy_derive::*;
5585    ///
5586    /// #[derive(FromBytes)]
5587    /// #[repr(C)]
5588    /// struct BitmapFileHeader {
5589    ///     signature: [u8; 2],
5590    ///     size: U32,
5591    ///     reserved: U64,
5592    ///     offset: U64,
5593    /// }
5594    ///
5595    /// let mut file = File::open("image.bin").unwrap();
5596    /// let header = BitmapFileHeader::read_from_io(&mut file).unwrap();
5597    /// ```
5598    #[cfg(feature = "std")]
5599    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
5600    #[inline(always)]
5601    fn read_from_io<R>(mut src: R) -> io::Result<Self>
5602    where
5603        Self: Sized,
5604        R: io::Read,
5605    {
5606        // NOTE(#2319, #2320): We do `buf.zero()` separately rather than
5607        // constructing `let buf = CoreMaybeUninit::zeroed()` because, if `Self`
5608        // contains padding bytes, then a typed copy of `CoreMaybeUninit<Self>`
5609        // will not necessarily preserve zeros written to those padding byte
5610        // locations, and so `buf` could contain uninitialized bytes.
5611        let mut buf = CoreMaybeUninit::<Self>::uninit();
5612        buf.zero();
5613
5614        let ptr = Ptr::from_mut(&mut buf);
5615        // SAFETY: After `buf.zero()`, `buf` consists entirely of initialized,
5616        // zeroed bytes. Since `MaybeUninit` has no validity requirements, `ptr`
5617        // cannot be used to write values which will violate `buf`'s bit
5618        // validity. Since `ptr` has `Exclusive` aliasing, nothing other than
5619        // `ptr` may be used to mutate `ptr`'s referent, and so its bit validity
5620        // cannot be violated even though `buf` may have more permissive bit
5621        // validity than `ptr`.
5622        let ptr = unsafe { ptr.assume_validity::<invariant::Initialized>() };
5623        let ptr = ptr.as_bytes();
5624        src.read_exact(ptr.as_mut())?;
5625        // SAFETY: `buf` entirely consists of initialized bytes, and `Self` is
5626        // `FromBytes`.
5627        Ok(unsafe { buf.assume_init() })
5628    }
5629
5630    #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::ref_from_bytes`")]
5631    #[doc(hidden)]
5632    #[must_use = "has no side effects"]
5633    #[inline(always)]
5634    fn ref_from(source: &[u8]) -> Option<&Self>
5635    where
5636        Self: KnownLayout + Immutable,
5637    {
5638        Self::ref_from_bytes(source).ok()
5639    }
5640
5641    #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::mut_from_bytes`")]
5642    #[doc(hidden)]
5643    #[must_use = "has no side effects"]
5644    #[inline(always)]
5645    fn mut_from(source: &mut [u8]) -> Option<&mut Self>
5646    where
5647        Self: KnownLayout + IntoBytes,
5648    {
5649        Self::mut_from_bytes(source).ok()
5650    }
5651
5652    #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::ref_from_prefix_with_elems`")]
5653    #[doc(hidden)]
5654    #[must_use = "has no side effects"]
5655    #[inline(always)]
5656    fn slice_from_prefix(source: &[u8], count: usize) -> Option<(&[Self], &[u8])>
5657    where
5658        Self: Sized + Immutable,
5659    {
5660        <[Self]>::ref_from_prefix_with_elems(source, count).ok()
5661    }
5662
5663    #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::ref_from_suffix_with_elems`")]
5664    #[doc(hidden)]
5665    #[must_use = "has no side effects"]
5666    #[inline(always)]
5667    fn slice_from_suffix(source: &[u8], count: usize) -> Option<(&[u8], &[Self])>
5668    where
5669        Self: Sized + Immutable,
5670    {
5671        <[Self]>::ref_from_suffix_with_elems(source, count).ok()
5672    }
5673
5674    #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::mut_from_prefix_with_elems`")]
5675    #[doc(hidden)]
5676    #[must_use = "has no side effects"]
5677    #[inline(always)]
5678    fn mut_slice_from_prefix(source: &mut [u8], count: usize) -> Option<(&mut [Self], &mut [u8])>
5679    where
5680        Self: Sized + IntoBytes,
5681    {
5682        <[Self]>::mut_from_prefix_with_elems(source, count).ok()
5683    }
5684
5685    #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::mut_from_suffix_with_elems`")]
5686    #[doc(hidden)]
5687    #[must_use = "has no side effects"]
5688    #[inline(always)]
5689    fn mut_slice_from_suffix(source: &mut [u8], count: usize) -> Option<(&mut [u8], &mut [Self])>
5690    where
5691        Self: Sized + IntoBytes,
5692    {
5693        <[Self]>::mut_from_suffix_with_elems(source, count).ok()
5694    }
5695
5696    #[deprecated(since = "0.8.0", note = "renamed to `FromBytes::read_from_bytes`")]
5697    #[doc(hidden)]
5698    #[must_use = "has no side effects"]
5699    #[inline(always)]
5700    fn read_from(source: &[u8]) -> Option<Self>
5701    where
5702        Self: Sized,
5703    {
5704        Self::read_from_bytes(source).ok()
5705    }
5706}
5707
5708/// Interprets the given affix of `source`'s bytes as a `&T`.
5709///
5710/// This method uses `meta` if provided; otherwise, it computes the largest
5711/// possible size of `T` that can fit in the prefix or suffix bytes of `source`.
5712/// It returns both a reference to those bytes interpreted as a `T`, and a
5713/// reference to the excess bytes. If there are insufficient bytes, or if that
5714/// affix of `source` is not appropriately aligned, this returns `Err` containing
5715/// the original `&S`.
5716#[inline(always)]
5717fn ref_from_prefix_suffix<S, T>(
5718    source: &S,
5719    meta: Option<T::PointerMetadata>,
5720    cast_type: CastType,
5721) -> Result<(&T, &[u8]), CastError<&S, T>>
5722where
5723    S: IntoBytes + Immutable + ?Sized,
5724    T: FromBytes + KnownLayout + Immutable + ?Sized,
5725{
5726    let (slf, prefix_suffix) = Ptr::from_ref(source.as_bytes())
5727        .try_cast_into::<_, BecauseImmutable>(cast_type, meta)
5728        .map_err(|err| {
5729            err.map_src(
5730                #[inline(always)]
5731                |_| source,
5732            )
5733        })?;
5734    Ok((slf.recall_validity().as_ref(), prefix_suffix.as_ref()))
5735}
5736
5737/// Interprets the given affix of the given bytes as a `&mut Self` without
5738/// copying.
5739///
5740/// This method computes the largest possible size of `Self` that can fit in the
5741/// prefix or suffix bytes of `source`, then attempts to return both a reference
5742/// to those bytes interpreted as a `Self`, and a reference to the excess bytes.
5743/// If there are insufficient bytes, or if that affix of `source` is not
5744/// appropriately aligned, this returns `Err`.
5745#[inline(always)]
5746fn mut_from_prefix_suffix<T: FromBytes + IntoBytes + KnownLayout + ?Sized>(
5747    source: &mut [u8],
5748    meta: Option<T::PointerMetadata>,
5749    cast_type: CastType,
5750) -> Result<(&mut T, &mut [u8]), CastError<&mut [u8], T>> {
5751    let (slf, prefix_suffix) = Ptr::from_mut(source)
5752        .try_cast_into::<_, BecauseExclusive>(cast_type, meta)
5753        .map_err(|err| err.map_src(|s| s.as_mut()))?;
5754    Ok((slf.recall_validity::<_, (_, (_, _))>().as_mut(), prefix_suffix.as_mut()))
5755}
5756
5757/// Analyzes whether a type is [`IntoBytes`].
5758///
5759/// This derive analyzes, at compile time, whether the annotated type satisfies
5760/// the [safety conditions] of `IntoBytes` and implements `IntoBytes` if it is
5761/// sound to do so. This derive can be applied to structs and enums (see below
5762/// for union support); e.g.:
5763///
5764/// ```
5765/// # use zerocopy_derive::{IntoBytes};
5766/// #[derive(IntoBytes)]
5767/// #[repr(C)]
5768/// struct MyStruct {
5769/// # /*
5770///     ...
5771/// # */
5772/// }
5773///
5774/// #[derive(IntoBytes)]
5775/// #[repr(u8)]
5776/// enum MyEnum {
5777/// #   Variant,
5778/// # /*
5779///     ...
5780/// # */
5781/// }
5782/// ```
5783///
5784/// [safety conditions]: trait@IntoBytes#safety
5785///
5786/// # Error Messages
5787///
5788/// On Rust toolchains prior to 1.78.0, due to the way that the custom derive
5789/// for `IntoBytes` is implemented, you may get an error like this:
5790///
5791/// ```text
5792/// error[E0277]: the trait bound `(): PaddingFree<Foo, true>` is not satisfied
5793///   --> lib.rs:23:10
5794///    |
5795///  1 | #[derive(IntoBytes)]
5796///    |          ^^^^^^^^^ the trait `PaddingFree<Foo, true>` is not implemented for `()`
5797///    |
5798///    = help: the following implementations were found:
5799///                   <() as PaddingFree<T, false>>
5800/// ```
5801///
5802/// This error indicates that the type being annotated has padding bytes, which
5803/// is illegal for `IntoBytes` types. Consider reducing the alignment of some
5804/// fields by using types in the [`byteorder`] module, wrapping field types in
5805/// [`Unalign`], adding explicit struct fields where those padding bytes would
5806/// be, or using `#[repr(packed)]`. See the Rust Reference's page on [type
5807/// layout] for more information about type layout and padding.
5808///
5809/// [type layout]: https://doc.rust-lang.org/reference/type-layout.html
5810///
5811/// # Unions
5812///
5813/// Currently, union bit validity is [up in the air][union-validity], and so
5814/// zerocopy does not support `#[derive(IntoBytes)]` on unions by default.
5815/// However, implementing `IntoBytes` on a union type is likely sound on all
5816/// existing Rust toolchains - it's just that it may become unsound in the
5817/// future. You can opt-in to `#[derive(IntoBytes)]` support on unions by
5818/// passing the unstable `zerocopy_derive_union_into_bytes` cfg:
5819///
5820/// ```shell
5821/// $ RUSTFLAGS='--cfg zerocopy_derive_union_into_bytes' cargo build
5822/// ```
5823///
5824/// However, it is your responsibility to ensure that this derive is sound on
5825/// the specific versions of the Rust toolchain you are using! We make no
5826/// stability or soundness guarantees regarding this cfg, and may remove it at
5827/// any point.
5828///
5829/// We are actively working with Rust to stabilize the necessary language
5830/// guarantees to support this in a forwards-compatible way, which will enable
5831/// us to remove the cfg gate. As part of this effort, we need to know how much
5832/// demand there is for this feature. If you would like to use `IntoBytes` on
5833/// unions, [please let us know][discussion].
5834///
5835/// [union-validity]: https://github.com/rust-lang/unsafe-code-guidelines/issues/438
5836/// [discussion]: https://github.com/google/zerocopy/discussions/1802
5837///
5838/// # Analysis
5839///
5840/// *This section describes, roughly, the analysis performed by this derive to
5841/// determine whether it is sound to implement `IntoBytes` for a given type.
5842/// Unless you are modifying the implementation of this derive, or attempting to
5843/// manually implement `IntoBytes` for a type yourself, you don't need to read
5844/// this section.*
5845///
5846/// If a type has the following properties, then this derive can implement
5847/// `IntoBytes` for that type:
5848///
5849/// - If the type is a struct, its fields must be [`IntoBytes`]. Additionally:
5850///     - if the type is `repr(transparent)` or `repr(packed)`, it is
5851///       [`IntoBytes`] if its fields are [`IntoBytes`]; else,
5852///     - if the type is `repr(C)` with at most one field, it is [`IntoBytes`]
5853///       if its field is [`IntoBytes`]; else,
5854///     - if the type has no generic parameters, it is [`IntoBytes`] if the type
5855///       is sized and has no padding bytes; else,
5856///     - if the type is `repr(C)` without an `align(N)` modifier for `N > 1`
5857///       (it may have `align(1)` or `packed(N)`), and every field is `T`,
5858///       `[T; N]`, or a final `[T]` for the same type parameter `T`, it is
5859///       [`IntoBytes`]; else,
5860///     - if the type is `repr(C)`, its fields must be [`Unaligned`].
5861/// - If the type is an enum:
5862///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
5863///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
5864///   - It must have no padding bytes.
5865///   - Its fields must be [`IntoBytes`].
5866///
5867/// This analysis is subject to change. Unsafe code may *only* rely on the
5868/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
5869/// implementation details of this derive.
5870///
5871/// [Rust Reference]: https://doc.rust-lang.org/reference/type-layout.html
5872#[cfg(any(feature = "derive", test))]
5873#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
5874pub use zerocopy_derive::IntoBytes;
5875
5876/// Types that can be converted to an immutable slice of initialized bytes.
5877///
5878/// Any `IntoBytes` type can be converted to a slice of initialized bytes of the
5879/// same size. This is useful for efficiently serializing structured data as raw
5880/// bytes.
5881///
5882/// # Implementation
5883///
5884/// **Do not implement this trait yourself!** Instead, use
5885/// [`#[derive(IntoBytes)]`][derive]; e.g.:
5886///
5887/// ```
5888/// # use zerocopy_derive::IntoBytes;
5889/// #[derive(IntoBytes)]
5890/// #[repr(C)]
5891/// struct MyStruct {
5892/// # /*
5893///     ...
5894/// # */
5895/// }
5896///
5897/// #[derive(IntoBytes)]
5898/// #[repr(u8)]
5899/// enum MyEnum {
5900/// #   Variant0,
5901/// # /*
5902///     ...
5903/// # */
5904/// }
5905/// ```
5906///
5907/// This derive performs a sophisticated, compile-time safety analysis to
5908/// determine whether a type is `IntoBytes`. See the [derive
5909/// documentation][derive] for guidance on how to interpret error messages
5910/// produced by the derive's analysis.
5911///
5912/// # Safety
5913///
5914/// *This section describes what is required in order for `T: IntoBytes`, and
5915/// what unsafe code may assume of such types. If you don't plan on implementing
5916/// `IntoBytes` manually, and you don't plan on writing unsafe code that
5917/// operates on `IntoBytes` types, then you don't need to read this section.*
5918///
5919/// If `T: IntoBytes`, then unsafe code may assume that it is sound to treat any
5920/// `t: T` as an immutable `[u8]` of length `size_of_val(t)`. If a type is
5921/// marked as `IntoBytes` which violates this contract, it may cause undefined
5922/// behavior.
5923///
5924/// `#[derive(IntoBytes)]` only permits [types which satisfy these
5925/// requirements][derive-analysis].
5926///
5927#[cfg_attr(
5928    feature = "derive",
5929    doc = "[derive]: zerocopy_derive::IntoBytes",
5930    doc = "[derive-analysis]: zerocopy_derive::IntoBytes#analysis"
5931)]
5932#[cfg_attr(
5933    not(feature = "derive"),
5934    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.IntoBytes.html"),
5935    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.IntoBytes.html#analysis"),
5936)]
5937#[cfg_attr(
5938    not(no_zerocopy_diagnostic_on_unimplemented_1_78_0),
5939    diagnostic::on_unimplemented(note = "Consider adding `#[derive(IntoBytes)]` to `{Self}`")
5940)]
5941pub unsafe trait IntoBytes {
5942    // The `Self: Sized` bound makes it so that this function doesn't prevent
5943    // `IntoBytes` from being object safe. Note that other `IntoBytes` methods
5944    // prevent object safety, but those provide a benefit in exchange for object
5945    // safety. If at some point we remove those methods, change their type
5946    // signatures, or move them out of this trait so that `IntoBytes` is object
5947    // safe again, it's important that this function not prevent object safety.
5948    #[doc(hidden)]
5949    fn only_derive_is_allowed_to_implement_this_trait()
5950    where
5951        Self: Sized;
5952
5953    /// Gets the bytes of this value.
5954    ///
5955    /// # Examples
5956    ///
5957    /// ```
5958    /// use zerocopy::IntoBytes;
5959    /// # use zerocopy_derive::*;
5960    ///
5961    /// #[derive(IntoBytes, Immutable)]
5962    /// #[repr(C)]
5963    /// struct PacketHeader {
5964    ///     src_port: [u8; 2],
5965    ///     dst_port: [u8; 2],
5966    ///     length: [u8; 2],
5967    ///     checksum: [u8; 2],
5968    /// }
5969    ///
5970    /// let header = PacketHeader {
5971    ///     src_port: [0, 1],
5972    ///     dst_port: [2, 3],
5973    ///     length: [4, 5],
5974    ///     checksum: [6, 7],
5975    /// };
5976    ///
5977    /// let bytes = header.as_bytes();
5978    ///
5979    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
5980    /// ```
5981    ///
5982    #[doc = codegen_section!(
5983        header = "h5",
5984        bench = "as_bytes",
5985        format = "coco",
5986        arity = 2,
5987        [
5988            open
5989            @index 1
5990            @title "Sized"
5991            @variant "static_size"
5992        ],
5993        [
5994            @index 2
5995            @title "Unsized"
5996            @variant "dynamic_size"
5997        ]
5998    )]
5999    #[must_use = "has no side effects"]
6000    #[inline(always)]
6001    fn as_bytes(&self) -> &[u8]
6002    where
6003        Self: Immutable,
6004    {
6005        // Note that this method does not have a `Self: Sized` bound;
6006        // `size_of_val` works for unsized values too.
6007        let len = mem::size_of_val(self);
6008        let slf: *const Self = self;
6009
6010        // SAFETY:
6011        // - `slf.cast::<u8>()` is valid for reads for `len * size_of::<u8>()`
6012        //   many bytes because...
6013        //   - `slf` is the same pointer as `self`, and `self` is a reference
6014        //     which points to an object whose size is `len`. Thus...
6015        //     - The entire region of `len` bytes starting at `slf` is contained
6016        //       within a single allocation.
6017        //     - `slf` is non-null.
6018        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
6019        // - `Self: IntoBytes` ensures that all of the bytes of `slf` are
6020        //   initialized.
6021        // - Since `slf` is derived from `self`, and `self` is an immutable
6022        //   reference, the only other references to this memory region that
6023        //   could exist are other immutable references, which by `Self:
6024        //   Immutable` don't permit mutation.
6025        // - The total size of the resulting slice is no larger than
6026        //   `isize::MAX` because no allocation produced by safe code can be
6027        //   larger than `isize::MAX`.
6028        //
6029        // FIXME(#429): Add references to docs and quotes.
6030        unsafe { slice::from_raw_parts(slf.cast::<u8>(), len) }
6031    }
6032
6033    /// Gets the bytes of this value mutably.
6034    ///
6035    /// # Examples
6036    ///
6037    /// ```
6038    /// use zerocopy::IntoBytes;
6039    /// # use zerocopy_derive::*;
6040    ///
6041    /// # #[derive(Eq, PartialEq, Debug)]
6042    /// #[derive(FromBytes, IntoBytes, Immutable)]
6043    /// #[repr(C)]
6044    /// struct PacketHeader {
6045    ///     src_port: [u8; 2],
6046    ///     dst_port: [u8; 2],
6047    ///     length: [u8; 2],
6048    ///     checksum: [u8; 2],
6049    /// }
6050    ///
6051    /// let mut header = PacketHeader {
6052    ///     src_port: [0, 1],
6053    ///     dst_port: [2, 3],
6054    ///     length: [4, 5],
6055    ///     checksum: [6, 7],
6056    /// };
6057    ///
6058    /// let bytes = header.as_mut_bytes();
6059    ///
6060    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
6061    ///
6062    /// bytes.reverse();
6063    ///
6064    /// assert_eq!(header, PacketHeader {
6065    ///     src_port: [7, 6],
6066    ///     dst_port: [5, 4],
6067    ///     length: [3, 2],
6068    ///     checksum: [1, 0],
6069    /// });
6070    /// ```
6071    ///
6072    #[doc = codegen_header!("h5", "as_mut_bytes")]
6073    ///
6074    /// See [`IntoBytes::as_bytes`](#method.as_bytes.codegen).
6075    #[must_use = "has no side effects"]
6076    #[inline(always)]
6077    fn as_mut_bytes(&mut self) -> &mut [u8]
6078    where
6079        Self: FromBytes,
6080    {
6081        // Note that this method does not have a `Self: Sized` bound;
6082        // `size_of_val` works for unsized values too.
6083        let len = mem::size_of_val(self);
6084        let slf: *mut Self = self;
6085
6086        // SAFETY:
6087        // - `slf.cast::<u8>()` is valid for reads and writes for `len *
6088        //   size_of::<u8>()` many bytes because...
6089        //   - `slf` is the same pointer as `self`, and `self` is a reference
6090        //     which points to an object whose size is `len`. Thus...
6091        //     - The entire region of `len` bytes starting at `slf` is contained
6092        //       within a single allocation.
6093        //     - `slf` is non-null.
6094        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
6095        // - `Self: IntoBytes` ensures that all of the bytes of `slf` are
6096        //   initialized.
6097        // - `Self: FromBytes` ensures that no write to this memory region
6098        //   could result in it containing an invalid `Self`.
6099        // - Since `slf` is derived from `self`, and `self` is a mutable
6100        //   reference, no other references to this memory region can exist.
6101        // - The total size of the resulting slice is no larger than
6102        //   `isize::MAX` because no allocation produced by safe code can be
6103        //   larger than `isize::MAX`.
6104        //
6105        // FIXME(#429): Add references to docs and quotes.
6106        unsafe { slice::from_raw_parts_mut(slf.cast::<u8>(), len) }
6107    }
6108
6109    /// Writes a copy of `self` to `dst`.
6110    ///
6111    /// If `dst.len() != size_of_val(self)`, `write_to` returns `Err`.
6112    ///
6113    /// # Examples
6114    ///
6115    /// ```
6116    /// use zerocopy::IntoBytes;
6117    /// # use zerocopy_derive::*;
6118    ///
6119    /// #[derive(IntoBytes, Immutable)]
6120    /// #[repr(C)]
6121    /// struct PacketHeader {
6122    ///     src_port: [u8; 2],
6123    ///     dst_port: [u8; 2],
6124    ///     length: [u8; 2],
6125    ///     checksum: [u8; 2],
6126    /// }
6127    ///
6128    /// let header = PacketHeader {
6129    ///     src_port: [0, 1],
6130    ///     dst_port: [2, 3],
6131    ///     length: [4, 5],
6132    ///     checksum: [6, 7],
6133    /// };
6134    ///
6135    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0];
6136    ///
6137    /// header.write_to(&mut bytes[..]);
6138    ///
6139    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
6140    /// ```
6141    ///
6142    /// If too many or too few target bytes are provided, `write_to` returns
6143    /// `Err` and leaves the target bytes unmodified:
6144    ///
6145    /// ```
6146    /// # use zerocopy::IntoBytes;
6147    /// # let header = u128::MAX;
6148    /// let mut excessive_bytes = &mut [0u8; 128][..];
6149    ///
6150    /// let write_result = header.write_to(excessive_bytes);
6151    ///
6152    /// assert!(write_result.is_err());
6153    /// assert_eq!(excessive_bytes, [0u8; 128]);
6154    /// ```
6155    ///
6156    #[doc = codegen_section!(
6157        header = "h5",
6158        bench = "write_to",
6159        format = "coco",
6160        arity = 2,
6161        [
6162            open
6163            @index 1
6164            @title "Sized"
6165            @variant "static_size"
6166        ],
6167        [
6168            @index 2
6169            @title "Unsized"
6170            @variant "dynamic_size"
6171        ]
6172    )]
6173    #[must_use = "callers should check the return value to see if the operation succeeded"]
6174    #[cfg_attr(zerocopy_inline_always, inline(always))]
6175    #[cfg_attr(not(zerocopy_inline_always), inline)]
6176    #[allow(clippy::mut_from_ref)] // False positive: `&self -> &mut [u8]`
6177    fn write_to(&self, dst: &mut [u8]) -> Result<(), SizeError<&Self, &mut [u8]>>
6178    where
6179        Self: Immutable,
6180    {
6181        let src = self.as_bytes();
6182        if dst.len() == src.len() {
6183            // SAFETY: Within this branch of the conditional, we have ensured
6184            // that `dst.len()` is equal to `src.len()`. Neither the size of the
6185            // source nor the size of the destination change between the above
6186            // size check and the invocation of `copy_unchecked`.
6187            unsafe { util::copy_unchecked(src, dst) }
6188            Ok(())
6189        } else {
6190            Err(SizeError::new(self))
6191        }
6192    }
6193
6194    /// Writes a copy of `self` to the prefix of `dst`.
6195    ///
6196    /// `write_to_prefix` writes `self` to the first `size_of_val(self)` bytes
6197    /// of `dst`. If `dst.len() < size_of_val(self)`, it returns `Err`.
6198    ///
6199    /// # Examples
6200    ///
6201    /// ```
6202    /// use zerocopy::IntoBytes;
6203    /// # use zerocopy_derive::*;
6204    ///
6205    /// #[derive(IntoBytes, Immutable)]
6206    /// #[repr(C)]
6207    /// struct PacketHeader {
6208    ///     src_port: [u8; 2],
6209    ///     dst_port: [u8; 2],
6210    ///     length: [u8; 2],
6211    ///     checksum: [u8; 2],
6212    /// }
6213    ///
6214    /// let header = PacketHeader {
6215    ///     src_port: [0, 1],
6216    ///     dst_port: [2, 3],
6217    ///     length: [4, 5],
6218    ///     checksum: [6, 7],
6219    /// };
6220    ///
6221    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
6222    ///
6223    /// header.write_to_prefix(&mut bytes[..]);
6224    ///
6225    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7, 0, 0]);
6226    /// ```
6227    ///
6228    /// If insufficient target bytes are provided, `write_to_prefix` returns
6229    /// `Err` and leaves the target bytes unmodified:
6230    ///
6231    /// ```
6232    /// # use zerocopy::IntoBytes;
6233    /// # let header = u128::MAX;
6234    /// let mut insufficient_bytes = &mut [0, 0][..];
6235    ///
6236    /// let write_result = header.write_to_suffix(insufficient_bytes);
6237    ///
6238    /// assert!(write_result.is_err());
6239    /// assert_eq!(insufficient_bytes, [0, 0]);
6240    /// ```
6241    ///
6242    #[doc = codegen_section!(
6243        header = "h5",
6244        bench = "write_to_prefix",
6245        format = "coco",
6246        arity = 2,
6247        [
6248            open
6249            @index 1
6250            @title "Sized"
6251            @variant "static_size"
6252        ],
6253        [
6254            @index 2
6255            @title "Unsized"
6256            @variant "dynamic_size"
6257        ]
6258    )]
6259    #[must_use = "callers should check the return value to see if the operation succeeded"]
6260    #[cfg_attr(zerocopy_inline_always, inline(always))]
6261    #[cfg_attr(not(zerocopy_inline_always), inline)]
6262    #[allow(clippy::mut_from_ref)] // False positive: `&self -> &mut [u8]`
6263    fn write_to_prefix(&self, dst: &mut [u8]) -> Result<(), SizeError<&Self, &mut [u8]>>
6264    where
6265        Self: Immutable,
6266    {
6267        let src = self.as_bytes();
6268        match dst.get_mut(..src.len()) {
6269            Some(dst) => {
6270                // SAFETY: Within this branch of the `match`, we have ensured
6271                // through fallible subslicing that `dst.len()` is equal to
6272                // `src.len()`. Neither the size of the source nor the size of
6273                // the destination change between the above subslicing operation
6274                // and the invocation of `copy_unchecked`.
6275                unsafe { util::copy_unchecked(src, dst) }
6276                Ok(())
6277            }
6278            None => Err(SizeError::new(self)),
6279        }
6280    }
6281
6282    /// Writes a copy of `self` to the suffix of `dst`.
6283    ///
6284    /// `write_to_suffix` writes `self` to the last `size_of_val(self)` bytes of
6285    /// `dst`. If `dst.len() < size_of_val(self)`, it returns `Err`.
6286    ///
6287    /// # Examples
6288    ///
6289    /// ```
6290    /// use zerocopy::IntoBytes;
6291    /// # use zerocopy_derive::*;
6292    ///
6293    /// #[derive(IntoBytes, Immutable)]
6294    /// #[repr(C)]
6295    /// struct PacketHeader {
6296    ///     src_port: [u8; 2],
6297    ///     dst_port: [u8; 2],
6298    ///     length: [u8; 2],
6299    ///     checksum: [u8; 2],
6300    /// }
6301    ///
6302    /// let header = PacketHeader {
6303    ///     src_port: [0, 1],
6304    ///     dst_port: [2, 3],
6305    ///     length: [4, 5],
6306    ///     checksum: [6, 7],
6307    /// };
6308    ///
6309    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
6310    ///
6311    /// header.write_to_suffix(&mut bytes[..]);
6312    ///
6313    /// assert_eq!(bytes, [0, 0, 0, 1, 2, 3, 4, 5, 6, 7]);
6314    ///
6315    /// let mut insufficient_bytes = &mut [0, 0][..];
6316    ///
6317    /// let write_result = header.write_to_suffix(insufficient_bytes);
6318    ///
6319    /// assert!(write_result.is_err());
6320    /// assert_eq!(insufficient_bytes, [0, 0]);
6321    /// ```
6322    ///
6323    /// If insufficient target bytes are provided, `write_to_suffix` returns
6324    /// `Err` and leaves the target bytes unmodified:
6325    ///
6326    /// ```
6327    /// # use zerocopy::IntoBytes;
6328    /// # let header = u128::MAX;
6329    /// let mut insufficient_bytes = &mut [0, 0][..];
6330    ///
6331    /// let write_result = header.write_to_suffix(insufficient_bytes);
6332    ///
6333    /// assert!(write_result.is_err());
6334    /// assert_eq!(insufficient_bytes, [0, 0]);
6335    /// ```
6336    ///
6337    #[doc = codegen_section!(
6338        header = "h5",
6339        bench = "write_to_suffix",
6340        format = "coco",
6341        arity = 2,
6342        [
6343            open
6344            @index 1
6345            @title "Sized"
6346            @variant "static_size"
6347        ],
6348        [
6349            @index 2
6350            @title "Unsized"
6351            @variant "dynamic_size"
6352        ]
6353    )]
6354    #[must_use = "callers should check the return value to see if the operation succeeded"]
6355    #[cfg_attr(zerocopy_inline_always, inline(always))]
6356    #[cfg_attr(not(zerocopy_inline_always), inline)]
6357    #[allow(clippy::mut_from_ref)] // False positive: `&self -> &mut [u8]`
6358    fn write_to_suffix(&self, dst: &mut [u8]) -> Result<(), SizeError<&Self, &mut [u8]>>
6359    where
6360        Self: Immutable,
6361    {
6362        let src = self.as_bytes();
6363        let start = if let Some(start) = dst.len().checked_sub(src.len()) {
6364            start
6365        } else {
6366            return Err(SizeError::new(self));
6367        };
6368        let dst = if let Some(dst) = dst.get_mut(start..) {
6369            dst
6370        } else {
6371            // get_mut() should never return None here. We return a `SizeError`
6372            // rather than .unwrap() because in the event the branch is not
6373            // optimized away, returning a value is generally lighter-weight
6374            // than panicking.
6375            return Err(SizeError::new(self));
6376        };
6377        // SAFETY: Through fallible subslicing of `dst`, we have ensured that
6378        // `dst.len()` is equal to `src.len()`. Neither the size of the source
6379        // nor the size of the destination change between the above subslicing
6380        // operation and the invocation of `copy_unchecked`.
6381        unsafe {
6382            util::copy_unchecked(src, dst);
6383        }
6384        Ok(())
6385    }
6386
6387    /// Writes a copy of `self` to an `io::Write`.
6388    ///
6389    /// This is a shorthand for `dst.write_all(self.as_bytes())`, and is useful
6390    /// for interfacing with operating system byte sinks (files, sockets, etc.).
6391    ///
6392    /// # Examples
6393    ///
6394    /// ```no_run
6395    /// use zerocopy::{byteorder::big_endian::U16, FromBytes, IntoBytes};
6396    /// use std::fs::File;
6397    /// # use zerocopy_derive::*;
6398    ///
6399    /// #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
6400    /// #[repr(C, packed)]
6401    /// struct GrayscaleImage {
6402    ///     height: U16,
6403    ///     width: U16,
6404    ///     pixels: [U16],
6405    /// }
6406    ///
6407    /// let image = GrayscaleImage::ref_from_bytes(&[0, 0, 0, 0][..]).unwrap();
6408    /// let mut file = File::create("image.bin").unwrap();
6409    /// image.write_to_io(&mut file).unwrap();
6410    /// ```
6411    ///
6412    /// If the write fails, `write_to_io` returns `Err` and a partial write may
6413    /// have occurred; e.g.:
6414    ///
6415    /// ```
6416    /// # use zerocopy::IntoBytes;
6417    ///
6418    /// let src = u128::MAX;
6419    /// let mut dst = [0u8; 2];
6420    ///
6421    /// let write_result = src.write_to_io(&mut dst[..]);
6422    ///
6423    /// assert!(write_result.is_err());
6424    /// assert_eq!(dst, [255, 255]);
6425    /// ```
6426    #[cfg(feature = "std")]
6427    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
6428    #[inline(always)]
6429    fn write_to_io<W>(&self, mut dst: W) -> io::Result<()>
6430    where
6431        Self: Immutable,
6432        W: io::Write,
6433    {
6434        dst.write_all(self.as_bytes())
6435    }
6436
6437    #[deprecated(since = "0.8.0", note = "`IntoBytes::as_bytes_mut` was renamed to `as_mut_bytes`")]
6438    #[doc(hidden)]
6439    #[inline]
6440    fn as_bytes_mut(&mut self) -> &mut [u8]
6441    where
6442        Self: FromBytes,
6443    {
6444        self.as_mut_bytes()
6445    }
6446}
6447
6448/// Analyzes whether a type is [`Unaligned`].
6449///
6450/// This derive analyzes, at compile time, whether the annotated type satisfies
6451/// the [safety conditions] of `Unaligned` and implements `Unaligned` if it is
6452/// sound to do so. This derive can be applied to structs, enums, and unions;
6453/// e.g.:
6454///
6455/// ```
6456/// # use zerocopy_derive::Unaligned;
6457/// #[derive(Unaligned)]
6458/// #[repr(C)]
6459/// struct MyStruct {
6460/// # /*
6461///     ...
6462/// # */
6463/// }
6464///
6465/// #[derive(Unaligned)]
6466/// #[repr(u8)]
6467/// enum MyEnum {
6468/// #   Variant0,
6469/// # /*
6470///     ...
6471/// # */
6472/// }
6473///
6474/// #[derive(Unaligned)]
6475/// #[repr(packed)]
6476/// union MyUnion {
6477/// #   variant: u8,
6478/// # /*
6479///     ...
6480/// # */
6481/// }
6482/// ```
6483///
6484/// # Analysis
6485///
6486/// *This section describes, roughly, the analysis performed by this derive to
6487/// determine whether it is sound to implement `Unaligned` for a given type.
6488/// Unless you are modifying the implementation of this derive, or attempting to
6489/// manually implement `Unaligned` for a type yourself, you don't need to read
6490/// this section.*
6491///
6492/// If a type has the following properties, then this derive can implement
6493/// `Unaligned` for that type:
6494///
6495/// - If the type is a struct or union:
6496///   - If `repr(align(N))` is provided, `N` must equal 1.
6497///   - If the type is `repr(C)` or `repr(transparent)`, all fields must be
6498///     [`Unaligned`].
6499///   - If the type is not `repr(C)` or `repr(transparent)`, it must be
6500///     `repr(packed)` or `repr(packed(1))`.
6501/// - If the type is an enum:
6502///   - If `repr(align(N))` is provided, `N` must equal 1.
6503///   - It must be a field-less enum (meaning that all variants have no fields).
6504///   - It must be `repr(i8)` or `repr(u8)`.
6505///
6506/// [safety conditions]: trait@Unaligned#safety
6507#[cfg(any(feature = "derive", test))]
6508#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
6509pub use zerocopy_derive::Unaligned;
6510
6511/// Types with no alignment requirement.
6512///
6513/// If `T: Unaligned`, then `align_of::<T>() == 1`.
6514///
6515/// # Implementation
6516///
6517/// **Do not implement this trait yourself!** Instead, use
6518/// [`#[derive(Unaligned)]`][derive]; e.g.:
6519///
6520/// ```
6521/// # use zerocopy_derive::Unaligned;
6522/// #[derive(Unaligned)]
6523/// #[repr(C)]
6524/// struct MyStruct {
6525/// # /*
6526///     ...
6527/// # */
6528/// }
6529///
6530/// #[derive(Unaligned)]
6531/// #[repr(u8)]
6532/// enum MyEnum {
6533/// #   Variant0,
6534/// # /*
6535///     ...
6536/// # */
6537/// }
6538///
6539/// #[derive(Unaligned)]
6540/// #[repr(packed)]
6541/// union MyUnion {
6542/// #   variant: u8,
6543/// # /*
6544///     ...
6545/// # */
6546/// }
6547/// ```
6548///
6549/// This derive performs a sophisticated, compile-time safety analysis to
6550/// determine whether a type is `Unaligned`.
6551///
6552/// # Safety
6553///
6554/// *This section describes what is required in order for `T: Unaligned`, and
6555/// what unsafe code may assume of such types. If you don't plan on implementing
6556/// `Unaligned` manually, and you don't plan on writing unsafe code that
6557/// operates on `Unaligned` types, then you don't need to read this section.*
6558///
6559/// If `T: Unaligned`, then unsafe code may assume that it is sound to produce a
6560/// reference to `T` at any memory location regardless of alignment. If a type
6561/// is marked as `Unaligned` which violates this contract, it may cause
6562/// undefined behavior.
6563///
6564/// `#[derive(Unaligned)]` only permits [types which satisfy these
6565/// requirements][derive-analysis].
6566///
6567#[cfg_attr(
6568    feature = "derive",
6569    doc = "[derive]: zerocopy_derive::Unaligned",
6570    doc = "[derive-analysis]: zerocopy_derive::Unaligned#analysis"
6571)]
6572#[cfg_attr(
6573    not(feature = "derive"),
6574    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.Unaligned.html"),
6575    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.Unaligned.html#analysis"),
6576)]
6577#[cfg_attr(
6578    not(no_zerocopy_diagnostic_on_unimplemented_1_78_0),
6579    diagnostic::on_unimplemented(note = "Consider adding `#[derive(Unaligned)]` to `{Self}`")
6580)]
6581pub unsafe trait Unaligned {
6582    // The `Self: Sized` bound makes it so that `Unaligned` is still object
6583    // safe.
6584    #[doc(hidden)]
6585    fn only_derive_is_allowed_to_implement_this_trait()
6586    where
6587        Self: Sized;
6588}
6589
6590/// Derives optimized [`PartialEq`] and [`Eq`] implementations.
6591///
6592/// This derive can be applied to structs and enums implementing both
6593/// [`Immutable`] and [`IntoBytes`]; e.g.:
6594///
6595/// ```
6596/// # use zerocopy_derive::{ByteEq, Immutable, IntoBytes};
6597/// #[derive(ByteEq, Immutable, IntoBytes)]
6598/// #[repr(C)]
6599/// struct MyStruct {
6600/// # /*
6601///     ...
6602/// # */
6603/// }
6604///
6605/// #[derive(ByteEq, Immutable, IntoBytes)]
6606/// #[repr(u8)]
6607/// enum MyEnum {
6608/// #   Variant,
6609/// # /*
6610///     ...
6611/// # */
6612/// }
6613/// ```
6614///
6615/// The standard library's [`derive(Eq, PartialEq)`][derive@PartialEq] computes
6616/// equality by individually comparing each field. Instead, the implementation
6617/// of [`PartialEq::eq`] emitted by `derive(ByteHash)` converts the entirety of
6618/// `self` and `other` to byte slices and compares those slices for equality.
6619/// This may have performance advantages.
6620#[cfg(any(feature = "derive", test))]
6621#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
6622pub use zerocopy_derive::ByteEq;
6623/// Derives an optimized [`Hash`] implementation.
6624///
6625/// This derive can be applied to structs and enums implementing both
6626/// [`Immutable`] and [`IntoBytes`]; e.g.:
6627///
6628/// ```
6629/// # use zerocopy_derive::{ByteHash, Immutable, IntoBytes};
6630/// #[derive(ByteHash, Immutable, IntoBytes)]
6631/// #[repr(C)]
6632/// struct MyStruct {
6633/// # /*
6634///     ...
6635/// # */
6636/// }
6637///
6638/// #[derive(ByteHash, Immutable, IntoBytes)]
6639/// #[repr(u8)]
6640/// enum MyEnum {
6641/// #   Variant,
6642/// # /*
6643///     ...
6644/// # */
6645/// }
6646/// ```
6647///
6648/// The standard library's [`derive(Hash)`][derive@Hash] produces hashes by
6649/// individually hashing each field and combining the results. Instead, the
6650/// implementations of [`Hash::hash()`] and [`Hash::hash_slice()`] generated by
6651/// `derive(ByteHash)` convert the entirety of `self` to a byte slice and hashes
6652/// it in a single call to [`Hasher::write()`]. This may have performance
6653/// advantages.
6654///
6655/// [`Hash`]: core::hash::Hash
6656/// [`Hash::hash()`]: core::hash::Hash::hash()
6657/// [`Hash::hash_slice()`]: core::hash::Hash::hash_slice()
6658#[cfg(any(feature = "derive", test))]
6659#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
6660pub use zerocopy_derive::ByteHash;
6661/// Implements [`SplitAt`].
6662///
6663/// This derive can be applied to structs; e.g.:
6664///
6665/// ```
6666/// # use zerocopy_derive::{ByteEq, Immutable, IntoBytes};
6667/// #[derive(ByteEq, Immutable, IntoBytes)]
6668/// #[repr(C)]
6669/// struct MyStruct {
6670/// # /*
6671///     ...
6672/// # */
6673/// }
6674/// ```
6675#[cfg(any(feature = "derive", test))]
6676#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
6677pub use zerocopy_derive::SplitAt;
6678
6679#[cfg(feature = "alloc")]
6680#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
6681#[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
6682mod alloc_support {
6683    use super::*;
6684
6685    /// Extends a `Vec<T>` by pushing `additional` new items onto the end of the
6686    /// vector. The new items are initialized with zeros.
6687    #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
6688    #[doc(hidden)]
6689    #[deprecated(since = "0.8.0", note = "moved to `FromZeros`")]
6690    #[inline(always)]
6691    pub fn extend_vec_zeroed<T: FromZeros>(
6692        v: &mut Vec<T>,
6693        additional: usize,
6694    ) -> Result<(), AllocError> {
6695        <T as FromZeros>::extend_vec_zeroed(v, additional)
6696    }
6697
6698    /// Inserts `additional` new items into `Vec<T>` at `position`. The new
6699    /// items are initialized with zeros.
6700    ///
6701    /// # Panics
6702    ///
6703    /// Panics if `position > v.len()`.
6704    #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
6705    #[doc(hidden)]
6706    #[deprecated(since = "0.8.0", note = "moved to `FromZeros`")]
6707    #[inline(always)]
6708    pub fn insert_vec_zeroed<T: FromZeros>(
6709        v: &mut Vec<T>,
6710        position: usize,
6711        additional: usize,
6712    ) -> Result<(), AllocError> {
6713        <T as FromZeros>::insert_vec_zeroed(v, position, additional)
6714    }
6715}
6716
6717#[cfg(feature = "alloc")]
6718#[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
6719#[doc(hidden)]
6720pub use alloc_support::*;
6721
6722#[cfg(test)]
6723#[allow(clippy::assertions_on_result_states, clippy::unreadable_literal)]
6724mod tests {
6725    use static_assertions::assert_impl_all;
6726
6727    use super::*;
6728    use crate::util::testutil::*;
6729
6730    // An unsized type.
6731    //
6732    // This is used to test the custom derives of our traits. The `[u8]` type
6733    // gets a hand-rolled impl, so it doesn't exercise our custom derives.
6734    #[derive(Debug, Eq, PartialEq, FromBytes, IntoBytes, Unaligned, Immutable)]
6735    #[repr(transparent)]
6736    struct Unsized([u8]);
6737
6738    impl Unsized {
6739        fn from_mut_slice(slc: &mut [u8]) -> &mut Unsized {
6740            // SAFETY: This *probably* sound - since the layouts of `[u8]` and
6741            // `Unsized` are the same, so are the layouts of `&mut [u8]` and
6742            // `&mut Unsized`. [1] Even if it turns out that this isn't actually
6743            // guaranteed by the language spec, we can just change this since
6744            // it's in test code.
6745            //
6746            // [1] https://github.com/rust-lang/unsafe-code-guidelines/issues/375
6747            unsafe { mem::transmute(slc) }
6748        }
6749    }
6750
6751    #[test]
6752    fn test_known_layout() {
6753        // Test that `$ty` and `ManuallyDrop<$ty>` have the expected layout.
6754        // Test that `PhantomData<$ty>` has the same layout as `()` regardless
6755        // of `$ty`.
6756        macro_rules! test {
6757            ($ty:ty, $expect:expr) => {
6758                let expect = $expect;
6759                assert_eq!(<$ty as KnownLayout>::LAYOUT, expect);
6760                assert_eq!(<ManuallyDrop<$ty> as KnownLayout>::LAYOUT, expect);
6761                assert_eq!(<PhantomData<$ty> as KnownLayout>::LAYOUT, <() as KnownLayout>::LAYOUT);
6762            };
6763        }
6764
6765        let layout =
6766            |offset, align, trailing_slice_elem_size, statically_shallow_unpadded| DstLayout {
6767                align: NonZeroUsize::new(align).unwrap(),
6768                size_info: match trailing_slice_elem_size {
6769                    None => SizeInfo::Sized { size: offset },
6770                    Some(elem_size) => {
6771                        SizeInfo::SliceDst(TrailingSliceLayout { offset, elem_size })
6772                    }
6773                },
6774                statically_shallow_unpadded,
6775            };
6776
6777        test!((), layout(0, 1, None, false));
6778        test!(u8, layout(1, 1, None, false));
6779        // Use `align_of` because `u64` alignment may be smaller than 8 on some
6780        // platforms.
6781        test!(u64, layout(8, mem::align_of::<u64>(), None, false));
6782        test!(AU64, layout(8, 8, None, false));
6783
6784        test!(Option<&'static ()>, usize::LAYOUT);
6785
6786        test!([()], layout(0, 1, Some(0), true));
6787        test!([u8], layout(0, 1, Some(1), true));
6788        test!(str, layout(0, 1, Some(1), true));
6789    }
6790
6791    #[test]
6792    fn test_known_layout_pointer_to_metadata() {
6793        fn test<T>(data: *mut T, elems: usize) {
6794            let ptr = ptr::slice_from_raw_parts_mut(data, elems);
6795            assert_eq!(<[T] as KnownLayout>::pointer_to_metadata(ptr), elems);
6796        }
6797
6798        for elems in [0, 1, usize::MAX] {
6799            test(ptr::null_mut::<u8>(), elems);
6800        }
6801
6802        test(NonNull::<u8>::dangling().as_ptr(), 0);
6803
6804        let mut bytes = [1, 2, 3];
6805        test(bytes.as_mut_ptr(), bytes.len());
6806        assert_eq!(bytes, [1, 2, 3]);
6807
6808        test(NonNull::<()>::dangling().as_ptr(), usize::MAX);
6809
6810        // Retaining and inspecting a raw pointer after freeing its allocation
6811        // is safe so long as the pointer is not dereferenced.
6812        let deallocated = {
6813            let mut byte = Box::new(0u8);
6814            let ptr: *mut u8 = &mut *byte;
6815            drop(byte);
6816            ptr
6817        };
6818        test(deallocated, 3);
6819
6820        // Metadata extraction requires neither element storage nor alignment
6821        // for `T`; it does not access the pointer's referent.
6822        test(NonNull::<u8>::dangling().as_ptr().cast::<u64>(), usize::MAX);
6823    }
6824
6825    #[cfg(feature = "derive")]
6826    #[test]
6827    fn test_known_layout_pointer_to_metadata_derive() {
6828        #[derive(KnownLayout)]
6829        #[repr(C)]
6830        struct Dst {
6831            prefix: u8,
6832            trailing: [u8],
6833        }
6834
6835        for elems in [0, 1, usize::MAX] {
6836            let ptr = ptr::slice_from_raw_parts_mut(ptr::null_mut::<u8>(), elems);
6837            #[allow(clippy::as_conversions)]
6838            let ptr = ptr as *mut Dst;
6839            assert_eq!(Dst::pointer_to_metadata(ptr), elems);
6840        }
6841    }
6842
6843    #[cfg(feature = "derive")]
6844    #[test]
6845    fn test_known_layout_derive() {
6846        // In this and other files (`late_compile_pass.rs`,
6847        // `mid_compile_pass.rs`, and `struct.rs`), we test success and failure
6848        // modes of `derive(KnownLayout)` for the following combination of
6849        // properties:
6850        //
6851        // +------------+--------------------------------------+-----------+
6852        // |            |      trailing field properties       |           |
6853        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6854        // |------------+----------+----------------+----------+-----------|
6855        // |          N |        N |              N |        N |      KL00 |
6856        // |          N |        N |              N |        Y |      KL01 |
6857        // |          N |        N |              Y |        N |      KL02 |
6858        // |          N |        N |              Y |        Y |      KL03 |
6859        // |          N |        Y |              N |        N |      KL04 |
6860        // |          N |        Y |              N |        Y |      KL05 |
6861        // |          N |        Y |              Y |        N |      KL06 |
6862        // |          N |        Y |              Y |        Y |      KL07 |
6863        // |          Y |        N |              N |        N |      KL08 |
6864        // |          Y |        N |              N |        Y |      KL09 |
6865        // |          Y |        N |              Y |        N |      KL10 |
6866        // |          Y |        N |              Y |        Y |      KL11 |
6867        // |          Y |        Y |              N |        N |      KL12 |
6868        // |          Y |        Y |              N |        Y |      KL13 |
6869        // |          Y |        Y |              Y |        N |      KL14 |
6870        // |          Y |        Y |              Y |        Y |      KL15 |
6871        // +------------+----------+----------------+----------+-----------+
6872
6873        struct NotKnownLayout<T = ()> {
6874            _t: T,
6875        }
6876
6877        #[derive(KnownLayout)]
6878        #[repr(C)]
6879        struct AlignSize<const ALIGN: usize, const SIZE: usize>
6880        where
6881            elain::Align<ALIGN>: elain::Alignment,
6882        {
6883            _align: elain::Align<ALIGN>,
6884            size: [u8; SIZE],
6885        }
6886
6887        type AU16 = AlignSize<2, 2>;
6888        type AU32 = AlignSize<4, 4>;
6889
6890        fn _assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
6891
6892        let sized_layout = |align, size| DstLayout {
6893            align: NonZeroUsize::new(align).unwrap(),
6894            size_info: SizeInfo::Sized { size },
6895            statically_shallow_unpadded: false,
6896        };
6897
6898        let unsized_layout = |align, elem_size, offset, statically_shallow_unpadded| DstLayout {
6899            align: NonZeroUsize::new(align).unwrap(),
6900            size_info: SizeInfo::SliceDst(TrailingSliceLayout { offset, elem_size }),
6901            statically_shallow_unpadded,
6902        };
6903
6904        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6905        // |          N |        N |              N |        Y |      KL01 |
6906        #[allow(dead_code)]
6907        #[derive(KnownLayout)]
6908        struct KL01(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6909
6910        let expected = DstLayout::for_type::<KL01>();
6911
6912        assert_eq!(<KL01 as KnownLayout>::LAYOUT, expected);
6913        assert_eq!(<KL01 as KnownLayout>::LAYOUT, sized_layout(4, 8));
6914
6915        // ...with `align(N)`:
6916        #[allow(dead_code)]
6917        #[derive(KnownLayout)]
6918        #[repr(align(64))]
6919        struct KL01Align(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6920
6921        let expected = DstLayout::for_type::<KL01Align>();
6922
6923        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, expected);
6924        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6925
6926        // ...with `packed`:
6927        #[allow(dead_code)]
6928        #[derive(KnownLayout)]
6929        #[repr(packed)]
6930        struct KL01Packed(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6931
6932        let expected = DstLayout::for_type::<KL01Packed>();
6933
6934        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, expected);
6935        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, sized_layout(1, 6));
6936
6937        // ...with `packed(N)`:
6938        #[allow(dead_code)]
6939        #[derive(KnownLayout)]
6940        #[repr(packed(2))]
6941        struct KL01PackedN(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6942
6943        assert_impl_all!(KL01PackedN: KnownLayout);
6944
6945        let expected = DstLayout::for_type::<KL01PackedN>();
6946
6947        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, expected);
6948        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6949
6950        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6951        // |          N |        N |              Y |        Y |      KL03 |
6952        #[allow(dead_code)]
6953        #[derive(KnownLayout)]
6954        struct KL03(NotKnownLayout, u8);
6955
6956        let expected = DstLayout::for_type::<KL03>();
6957
6958        assert_eq!(<KL03 as KnownLayout>::LAYOUT, expected);
6959        assert_eq!(<KL03 as KnownLayout>::LAYOUT, sized_layout(1, 1));
6960
6961        // ... with `align(N)`
6962        #[allow(dead_code)]
6963        #[derive(KnownLayout)]
6964        #[repr(align(64))]
6965        struct KL03Align(NotKnownLayout<AU32>, u8);
6966
6967        let expected = DstLayout::for_type::<KL03Align>();
6968
6969        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, expected);
6970        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6971
6972        // ... with `packed`:
6973        #[allow(dead_code)]
6974        #[derive(KnownLayout)]
6975        #[repr(packed)]
6976        struct KL03Packed(NotKnownLayout<AU32>, u8);
6977
6978        let expected = DstLayout::for_type::<KL03Packed>();
6979
6980        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, expected);
6981        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, sized_layout(1, 5));
6982
6983        // ... with `packed(N)`
6984        #[allow(dead_code)]
6985        #[derive(KnownLayout)]
6986        #[repr(packed(2))]
6987        struct KL03PackedN(NotKnownLayout<AU32>, u8);
6988
6989        assert_impl_all!(KL03PackedN: KnownLayout);
6990
6991        let expected = DstLayout::for_type::<KL03PackedN>();
6992
6993        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, expected);
6994        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6995
6996        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6997        // |          N |        Y |              N |        Y |      KL05 |
6998        #[allow(dead_code)]
6999        #[derive(KnownLayout)]
7000        struct KL05<T>(u8, T);
7001
7002        fn _test_kl05<T>(t: T) -> impl KnownLayout {
7003            KL05(0u8, t)
7004        }
7005
7006        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
7007        // |          N |        Y |              Y |        Y |      KL07 |
7008        #[allow(dead_code)]
7009        #[derive(KnownLayout)]
7010        struct KL07<T: KnownLayout>(u8, T);
7011
7012        fn _test_kl07<T: KnownLayout>(t: T) -> impl KnownLayout {
7013            let _ = KL07(0u8, t);
7014        }
7015
7016        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
7017        // |          Y |        N |              Y |        N |      KL10 |
7018        #[allow(dead_code)]
7019        #[derive(KnownLayout)]
7020        #[repr(C)]
7021        struct KL10(NotKnownLayout<AU32>, [u8]);
7022
7023        let expected = DstLayout::new_zst(None)
7024            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
7025            .extend(<[u8] as KnownLayout>::LAYOUT, None)
7026            .pad_to_align();
7027
7028        assert_eq!(<KL10 as KnownLayout>::LAYOUT, expected);
7029        assert_eq!(<KL10 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 4, false));
7030
7031        // ...with `align(N)`:
7032        #[allow(dead_code)]
7033        #[derive(KnownLayout)]
7034        #[repr(C, align(64))]
7035        struct KL10Align(NotKnownLayout<AU32>, [u8]);
7036
7037        let repr_align = NonZeroUsize::new(64);
7038
7039        let expected = DstLayout::new_zst(repr_align)
7040            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
7041            .extend(<[u8] as KnownLayout>::LAYOUT, None)
7042            .pad_to_align();
7043
7044        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, expected);
7045        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, unsized_layout(64, 1, 4, false));
7046
7047        // ...with `packed`:
7048        #[allow(dead_code)]
7049        #[derive(KnownLayout)]
7050        #[repr(C, packed)]
7051        struct KL10Packed(NotKnownLayout<AU32>, [u8]);
7052
7053        let repr_packed = NonZeroUsize::new(1);
7054
7055        let expected = DstLayout::new_zst(None)
7056            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
7057            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
7058            .pad_to_align();
7059
7060        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, expected);
7061        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, unsized_layout(1, 1, 4, false));
7062
7063        // ...with `packed(N)`:
7064        #[allow(dead_code)]
7065        #[derive(KnownLayout)]
7066        #[repr(C, packed(2))]
7067        struct KL10PackedN(NotKnownLayout<AU32>, [u8]);
7068
7069        let repr_packed = NonZeroUsize::new(2);
7070
7071        let expected = DstLayout::new_zst(None)
7072            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
7073            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
7074            .pad_to_align();
7075
7076        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, expected);
7077        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4, false));
7078
7079        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
7080        // |          Y |        N |              Y |        Y |      KL11 |
7081        #[allow(dead_code)]
7082        #[derive(KnownLayout)]
7083        #[repr(C)]
7084        struct KL11(NotKnownLayout<AU64>, u8);
7085
7086        let expected = DstLayout::new_zst(None)
7087            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
7088            .extend(<u8 as KnownLayout>::LAYOUT, None)
7089            .pad_to_align();
7090
7091        assert_eq!(<KL11 as KnownLayout>::LAYOUT, expected);
7092        assert_eq!(<KL11 as KnownLayout>::LAYOUT, sized_layout(8, 16));
7093
7094        // ...with `align(N)`:
7095        #[allow(dead_code)]
7096        #[derive(KnownLayout)]
7097        #[repr(C, align(64))]
7098        struct KL11Align(NotKnownLayout<AU64>, u8);
7099
7100        let repr_align = NonZeroUsize::new(64);
7101
7102        let expected = DstLayout::new_zst(repr_align)
7103            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
7104            .extend(<u8 as KnownLayout>::LAYOUT, None)
7105            .pad_to_align();
7106
7107        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, expected);
7108        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
7109
7110        // ...with `packed`:
7111        #[allow(dead_code)]
7112        #[derive(KnownLayout)]
7113        #[repr(C, packed)]
7114        struct KL11Packed(NotKnownLayout<AU64>, u8);
7115
7116        let repr_packed = NonZeroUsize::new(1);
7117
7118        let expected = DstLayout::new_zst(None)
7119            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
7120            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
7121            .pad_to_align();
7122
7123        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, expected);
7124        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, sized_layout(1, 9));
7125
7126        // ...with `packed(N)`:
7127        #[allow(dead_code)]
7128        #[derive(KnownLayout)]
7129        #[repr(C, packed(2))]
7130        struct KL11PackedN(NotKnownLayout<AU64>, u8);
7131
7132        let repr_packed = NonZeroUsize::new(2);
7133
7134        let expected = DstLayout::new_zst(None)
7135            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
7136            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
7137            .pad_to_align();
7138
7139        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, expected);
7140        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, sized_layout(2, 10));
7141
7142        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
7143        // |          Y |        Y |              Y |        N |      KL14 |
7144        #[allow(dead_code)]
7145        #[derive(KnownLayout)]
7146        #[repr(C)]
7147        struct KL14<T: ?Sized + KnownLayout>(u8, T);
7148
7149        fn _test_kl14<T: ?Sized + KnownLayout>(kl: &KL14<T>) {
7150            _assert_kl(kl)
7151        }
7152
7153        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
7154        // |          Y |        Y |              Y |        Y |      KL15 |
7155        #[allow(dead_code)]
7156        #[derive(KnownLayout)]
7157        #[repr(C)]
7158        struct KL15<T: KnownLayout>(u8, T);
7159
7160        fn _test_kl15<T: KnownLayout>(t: T) -> impl KnownLayout {
7161            let _ = KL15(0u8, t);
7162        }
7163
7164        // Test a variety of combinations of field types:
7165        //  - ()
7166        //  - u8
7167        //  - AU16
7168        //  - [()]
7169        //  - [u8]
7170        //  - [AU16]
7171
7172        #[allow(clippy::upper_case_acronyms, dead_code)]
7173        #[derive(KnownLayout)]
7174        #[repr(C)]
7175        struct KLTU<T, U: ?Sized>(T, U);
7176
7177        assert_eq!(<KLTU<(), ()> as KnownLayout>::LAYOUT, sized_layout(1, 0));
7178
7179        assert_eq!(<KLTU<(), u8> as KnownLayout>::LAYOUT, sized_layout(1, 1));
7180
7181        assert_eq!(<KLTU<(), AU16> as KnownLayout>::LAYOUT, sized_layout(2, 2));
7182
7183        assert_eq!(<KLTU<(), [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 0, false));
7184
7185        assert_eq!(<KLTU<(), [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0, false));
7186
7187        assert_eq!(<KLTU<(), [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 0, false));
7188
7189        assert_eq!(<KLTU<u8, ()> as KnownLayout>::LAYOUT, sized_layout(1, 1));
7190
7191        assert_eq!(<KLTU<u8, u8> as KnownLayout>::LAYOUT, sized_layout(1, 2));
7192
7193        assert_eq!(<KLTU<u8, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
7194
7195        assert_eq!(<KLTU<u8, [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 1, false));
7196
7197        assert_eq!(<KLTU<u8, [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1, false));
7198
7199        assert_eq!(<KLTU<u8, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2, false));
7200
7201        assert_eq!(<KLTU<AU16, ()> as KnownLayout>::LAYOUT, sized_layout(2, 2));
7202
7203        assert_eq!(<KLTU<AU16, u8> as KnownLayout>::LAYOUT, sized_layout(2, 4));
7204
7205        assert_eq!(<KLTU<AU16, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
7206
7207        assert_eq!(<KLTU<AU16, [()]> as KnownLayout>::LAYOUT, unsized_layout(2, 0, 2, false));
7208
7209        assert_eq!(<KLTU<AU16, [u8]> as KnownLayout>::LAYOUT, unsized_layout(2, 1, 2, false));
7210
7211        assert_eq!(<KLTU<AU16, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2, false));
7212
7213        // Test a variety of field counts.
7214
7215        #[derive(KnownLayout)]
7216        #[repr(C)]
7217        struct KLF0;
7218
7219        assert_eq!(<KLF0 as KnownLayout>::LAYOUT, sized_layout(1, 0));
7220
7221        #[derive(KnownLayout)]
7222        #[repr(C)]
7223        struct KLF1([u8]);
7224
7225        assert_eq!(<KLF1 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0, true));
7226
7227        #[derive(KnownLayout)]
7228        #[repr(C)]
7229        struct KLF2(NotKnownLayout<u8>, [u8]);
7230
7231        assert_eq!(<KLF2 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1, false));
7232
7233        #[derive(KnownLayout)]
7234        #[repr(C)]
7235        struct KLF3(NotKnownLayout<u8>, NotKnownLayout<AU16>, [u8]);
7236
7237        assert_eq!(<KLF3 as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4, false));
7238
7239        #[derive(KnownLayout)]
7240        #[repr(C)]
7241        struct KLF4(NotKnownLayout<u8>, NotKnownLayout<AU16>, NotKnownLayout<AU32>, [u8]);
7242
7243        assert_eq!(<KLF4 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 8, false));
7244    }
7245
7246    #[test]
7247    fn test_object_safety() {
7248        fn _takes_immutable(_: &dyn Immutable) {}
7249        fn _takes_unaligned(_: &dyn Unaligned) {}
7250    }
7251
7252    #[test]
7253    fn test_from_zeros_only() {
7254        // Test types that implement `FromZeros` but not `FromBytes`.
7255
7256        assert!(!bool::new_zeroed());
7257        assert_eq!(char::new_zeroed(), '\0');
7258
7259        #[cfg(feature = "alloc")]
7260        {
7261            assert_eq!(bool::new_box_zeroed(), Ok(Box::new(false)));
7262            assert_eq!(char::new_box_zeroed(), Ok(Box::new('\0')));
7263
7264            assert_eq!(
7265                <[bool]>::new_box_zeroed_with_elems(3).unwrap().as_ref(),
7266                [false, false, false]
7267            );
7268            assert_eq!(
7269                <[char]>::new_box_zeroed_with_elems(3).unwrap().as_ref(),
7270                ['\0', '\0', '\0']
7271            );
7272
7273            assert_eq!(bool::new_vec_zeroed(3).unwrap().as_ref(), [false, false, false]);
7274            assert_eq!(char::new_vec_zeroed(3).unwrap().as_ref(), ['\0', '\0', '\0']);
7275        }
7276
7277        let mut string = "hello".to_string();
7278        let s: &mut str = string.as_mut();
7279        assert_eq!(s, "hello");
7280        s.zero();
7281        assert_eq!(s, "\0\0\0\0\0");
7282    }
7283
7284    #[test]
7285    fn test_zst_count_preserved() {
7286        // Test that, when an explicit count is provided to for a type with a
7287        // ZST trailing slice element, that count is preserved. This is
7288        // important since, for such types, all element counts result in objects
7289        // of the same size, and so the correct behavior is ambiguous. However,
7290        // preserving the count as requested by the user is the behavior that we
7291        // document publicly.
7292
7293        // FromZeros methods
7294        #[cfg(feature = "alloc")]
7295        assert_eq!(<[()]>::new_box_zeroed_with_elems(3).unwrap().len(), 3);
7296        #[cfg(feature = "alloc")]
7297        assert_eq!(<()>::new_vec_zeroed(3).unwrap().len(), 3);
7298
7299        // FromBytes methods
7300        assert_eq!(<[()]>::ref_from_bytes_with_elems(&[][..], 3).unwrap().len(), 3);
7301        assert_eq!(<[()]>::ref_from_prefix_with_elems(&[][..], 3).unwrap().0.len(), 3);
7302        assert_eq!(<[()]>::ref_from_suffix_with_elems(&[][..], 3).unwrap().1.len(), 3);
7303        assert_eq!(<[()]>::mut_from_bytes_with_elems(&mut [][..], 3).unwrap().len(), 3);
7304        assert_eq!(<[()]>::mut_from_prefix_with_elems(&mut [][..], 3).unwrap().0.len(), 3);
7305        assert_eq!(<[()]>::mut_from_suffix_with_elems(&mut [][..], 3).unwrap().1.len(), 3);
7306    }
7307
7308    #[test]
7309    fn test_read_write() {
7310        const VAL: u64 = 0x12345678;
7311        #[cfg(target_endian = "big")]
7312        const VAL_BYTES: [u8; 8] = VAL.to_be_bytes();
7313        #[cfg(target_endian = "little")]
7314        const VAL_BYTES: [u8; 8] = VAL.to_le_bytes();
7315        const ZEROS: [u8; 8] = [0u8; 8];
7316
7317        // Test `FromBytes::{read_from, read_from_prefix, read_from_suffix}`.
7318
7319        assert_eq!(u64::read_from_bytes(&VAL_BYTES[..]), Ok(VAL));
7320        // The first 8 bytes are from `VAL_BYTES` and the second 8 bytes are all
7321        // zeros.
7322        let bytes_with_prefix: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
7323        assert_eq!(u64::read_from_prefix(&bytes_with_prefix[..]), Ok((VAL, &ZEROS[..])));
7324        assert_eq!(u64::read_from_suffix(&bytes_with_prefix[..]), Ok((&VAL_BYTES[..], 0)));
7325        // The first 8 bytes are all zeros and the second 8 bytes are from
7326        // `VAL_BYTES`
7327        let bytes_with_suffix: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
7328        assert_eq!(u64::read_from_prefix(&bytes_with_suffix[..]), Ok((0, &VAL_BYTES[..])));
7329        assert_eq!(u64::read_from_suffix(&bytes_with_suffix[..]), Ok((&ZEROS[..], VAL)));
7330
7331        // Test `IntoBytes::{write_to, write_to_prefix, write_to_suffix}`.
7332
7333        let mut bytes = [0u8; 8];
7334        assert_eq!(VAL.write_to(&mut bytes[..]), Ok(()));
7335        assert_eq!(bytes, VAL_BYTES);
7336        let mut bytes = [0u8; 16];
7337        assert_eq!(VAL.write_to_prefix(&mut bytes[..]), Ok(()));
7338        let want: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
7339        assert_eq!(bytes, want);
7340        let mut bytes = [0u8; 16];
7341        assert_eq!(VAL.write_to_suffix(&mut bytes[..]), Ok(()));
7342        let want: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
7343        assert_eq!(bytes, want);
7344    }
7345
7346    #[test]
7347    #[cfg(feature = "std")]
7348    fn test_read_io_with_padding_soundness() {
7349        // This test is designed to exhibit potential UB in
7350        // `FromBytes::read_from_io`. (see #2319, #2320).
7351
7352        // On most platforms (where `align_of::<u16>() == 2`), `WithPadding`
7353        // will have inter-field padding between `x` and `y`.
7354        #[derive(FromBytes)]
7355        #[repr(C)]
7356        struct WithPadding {
7357            x: u8,
7358            y: u16,
7359        }
7360        struct ReadsInRead;
7361        impl std::io::Read for ReadsInRead {
7362            fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
7363                // This body branches on every byte of `buf`, ensuring that it
7364                // exhibits UB if any byte of `buf` is uninitialized.
7365                if buf.iter().all(|&x| x == 0) {
7366                    Ok(buf.len())
7367                } else {
7368                    buf.iter_mut().for_each(|x| *x = 0);
7369                    Ok(buf.len())
7370                }
7371            }
7372        }
7373        assert!(matches!(WithPadding::read_from_io(ReadsInRead), Ok(WithPadding { x: 0, y: 0 })));
7374    }
7375
7376    #[test]
7377    #[cfg(feature = "std")]
7378    fn test_read_write_io() {
7379        let mut long_buffer = [0, 0, 0, 0];
7380        assert!(matches!(u16::MAX.write_to_io(&mut long_buffer[..]), Ok(())));
7381        assert_eq!(long_buffer, [255, 255, 0, 0]);
7382        assert!(matches!(u16::read_from_io(&long_buffer[..]), Ok(u16::MAX)));
7383
7384        let mut short_buffer = [0, 0];
7385        assert!(u32::MAX.write_to_io(&mut short_buffer[..]).is_err());
7386        assert_eq!(short_buffer, [255, 255]);
7387        assert!(u32::read_from_io(&short_buffer[..]).is_err());
7388    }
7389
7390    #[test]
7391    fn test_try_from_bytes_try_read_from() {
7392        assert_eq!(<bool as TryFromBytes>::try_read_from_bytes(&[0]), Ok(false));
7393        assert_eq!(<bool as TryFromBytes>::try_read_from_bytes(&[1]), Ok(true));
7394
7395        assert_eq!(<bool as TryFromBytes>::try_read_from_prefix(&[0, 2]), Ok((false, &[2][..])));
7396        assert_eq!(<bool as TryFromBytes>::try_read_from_prefix(&[1, 2]), Ok((true, &[2][..])));
7397
7398        assert_eq!(<bool as TryFromBytes>::try_read_from_suffix(&[2, 0]), Ok((&[2][..], false)));
7399        assert_eq!(<bool as TryFromBytes>::try_read_from_suffix(&[2, 1]), Ok((&[2][..], true)));
7400
7401        // If we don't pass enough bytes, it fails.
7402        assert!(matches!(
7403            <u8 as TryFromBytes>::try_read_from_bytes(&[]),
7404            Err(TryReadError::Size(_))
7405        ));
7406        assert!(matches!(
7407            <u8 as TryFromBytes>::try_read_from_prefix(&[]),
7408            Err(TryReadError::Size(_))
7409        ));
7410        assert!(matches!(
7411            <u8 as TryFromBytes>::try_read_from_suffix(&[]),
7412            Err(TryReadError::Size(_))
7413        ));
7414
7415        // If we pass too many bytes, it fails.
7416        assert!(matches!(
7417            <u8 as TryFromBytes>::try_read_from_bytes(&[0, 0]),
7418            Err(TryReadError::Size(_))
7419        ));
7420
7421        // If we pass an invalid value, it fails.
7422        assert!(matches!(
7423            <bool as TryFromBytes>::try_read_from_bytes(&[2]),
7424            Err(TryReadError::Validity(_))
7425        ));
7426        assert!(matches!(
7427            <bool as TryFromBytes>::try_read_from_prefix(&[2, 0]),
7428            Err(TryReadError::Validity(_))
7429        ));
7430        assert!(matches!(
7431            <bool as TryFromBytes>::try_read_from_suffix(&[0, 2]),
7432            Err(TryReadError::Validity(_))
7433        ));
7434
7435        // Reading from a misaligned buffer should still succeed. Since `AU64`'s
7436        // alignment is 8, and since we read from two adjacent addresses one
7437        // byte apart, it is guaranteed that at least one of them (though
7438        // possibly both) will be misaligned.
7439        let bytes: [u8; 9] = [0, 0, 0, 0, 0, 0, 0, 0, 0];
7440        assert_eq!(<AU64 as TryFromBytes>::try_read_from_bytes(&bytes[..8]), Ok(AU64(0)));
7441        assert_eq!(<AU64 as TryFromBytes>::try_read_from_bytes(&bytes[1..9]), Ok(AU64(0)));
7442
7443        assert_eq!(
7444            <AU64 as TryFromBytes>::try_read_from_prefix(&bytes[..8]),
7445            Ok((AU64(0), &[][..]))
7446        );
7447        assert_eq!(
7448            <AU64 as TryFromBytes>::try_read_from_prefix(&bytes[1..9]),
7449            Ok((AU64(0), &[][..]))
7450        );
7451
7452        assert_eq!(
7453            <AU64 as TryFromBytes>::try_read_from_suffix(&bytes[..8]),
7454            Ok((&[][..], AU64(0)))
7455        );
7456        assert_eq!(
7457            <AU64 as TryFromBytes>::try_read_from_suffix(&bytes[1..9]),
7458            Ok((&[][..], AU64(0)))
7459        );
7460    }
7461
7462    #[test]
7463    fn test_try_read_from_typed_source() {
7464        #[derive(IntoBytes, Immutable)]
7465        #[repr(transparent)]
7466        struct Source<T: ?Sized>(T);
7467
7468        fn check<S: IntoBytes + Immutable + ?Sized>(source: &S, valid: bool) {
7469            match try_read_from::<_, [bool; 4]>(source) {
7470                Ok(value) => {
7471                    assert!(valid);
7472                    assert_eq!(value, [false, true, false, true]);
7473                }
7474                Err(error) => {
7475                    assert!(!valid);
7476                    assert!(matches!(error, TryReadError::Validity(_)));
7477                    assert!(ptr::eq(error.into_src(), source));
7478                }
7479            }
7480
7481            let error = try_read_from::<_, [bool; 5]>(source).unwrap_err();
7482            assert!(matches!(error, TryReadError::Size(_)));
7483            assert!(ptr::eq(error.into_src(), source));
7484        }
7485
7486        for (value, valid) in [(u16::from_ne_bytes([0, 1]), true), (0x0202, false)] {
7487            let source = Source([value; 2]);
7488            check(&source, valid);
7489            let source: &Source<[u16]> = &source;
7490            check(source, valid);
7491        }
7492
7493        let source = Source([(); 2]);
7494        assert!(try_read_from::<_, ()>(&source).is_ok());
7495        let source: &Source<[()]> = &source;
7496        assert!(try_read_from::<_, ()>(source).is_ok());
7497    }
7498
7499    #[test]
7500    fn test_try_read_initialized_padding() {
7501        #[derive(KnownLayout, Immutable, Debug, PartialEq, Eq)]
7502        #[repr(C, align(8))]
7503        struct Padded(u8);
7504
7505        // SAFETY: `Padded` has only a `u8` field and padding, so all
7506        // initialized byte sequences are valid. Per
7507        // https://doc.rust-lang.org/1.93.1/reference/behavior-considered-undefined.html#invalid-values:
7508        //
7509        //   An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer
7510        //   must be initialized, i.e., must not be obtained from uninitialized
7511        //   memory.
7512        //
7513        //   A `struct`, tuple, and array requires all fields/elements to be
7514        //   valid at their respective type.
7515        const _: () = unsafe {
7516            unsafe_impl!(=> TryFromBytes for Padded; |candidate| {
7517                // Observe every byte while validation is running, including
7518                // padding that a typed move of `MaybeUninit<Padded>` could
7519                // discard. The returned `Padded` need not retain its padding.
7520                assert_eq!(candidate.as_bytes::<BecauseImmutable>().as_ref(), &[0xA5; 8]);
7521                true
7522            })
7523        };
7524
7525        let source = [0xA5; 8];
7526        assert_eq!(Padded::try_read_from_bytes(&source), Ok(Padded(0xA5)));
7527
7528        let prefix_source = [0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0];
7529        let (value, suffix) = Padded::try_read_from_prefix(&prefix_source).unwrap();
7530        assert_eq!(value, Padded(0xA5));
7531        assert!(ptr::eq(suffix, &prefix_source[8..]));
7532
7533        let suffix_source = [0, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5];
7534        let (prefix, value) = Padded::try_read_from_suffix(&suffix_source).unwrap();
7535        assert_eq!(value, Padded(0xA5));
7536        assert!(ptr::eq(prefix, &suffix_source[..1]));
7537    }
7538
7539    #[test]
7540    fn test_try_read_error_sources_and_zero_sized() {
7541        let invalid = [2, 3];
7542        for (error, source) in [
7543            (bool::try_read_from_bytes(&invalid[..1]).unwrap_err(), &invalid[..1]),
7544            (bool::try_read_from_prefix(&invalid).unwrap_err(), &invalid[..]),
7545            (bool::try_read_from_suffix(&invalid).unwrap_err(), &invalid[..]),
7546        ] {
7547            assert!(matches!(error, TryReadError::Validity(_)));
7548            assert!(ptr::eq(error.into_src(), source));
7549        }
7550        for source in [&[][..], &invalid[..]] {
7551            let error = bool::try_read_from_bytes(source).unwrap_err();
7552            assert!(matches!(error, TryReadError::Size(_)));
7553            assert!(ptr::eq(error.into_src(), source));
7554        }
7555        for error in [
7556            bool::try_read_from_prefix(&invalid[..0]).unwrap_err(),
7557            bool::try_read_from_suffix(&invalid[..0]).unwrap_err(),
7558        ] {
7559            assert!(matches!(error, TryReadError::Size(_)));
7560            assert!(ptr::eq(error.into_src(), &invalid[..0]));
7561        }
7562
7563        assert_eq!(<()>::try_read_from_bytes(&[]), Ok(()));
7564        assert_eq!(<()>::try_read_from_prefix(&invalid), Ok(((), &invalid[..])));
7565        assert_eq!(<()>::try_read_from_suffix(&invalid), Ok((&invalid[..], ())));
7566    }
7567
7568    #[test]
7569    fn test_ref_from_mut_from_bytes() {
7570        // Test `FromBytes::{ref_from_bytes, mut_from_bytes}{,_prefix,Suffix}`
7571        // success cases. Exhaustive coverage for these methods is covered by
7572        // the `Ref` tests above, which these helper methods defer to.
7573
7574        let mut buf =
7575            Align::<[u8; 16], AU64>::new([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
7576
7577        assert_eq!(
7578            AU64::ref_from_bytes(&buf.t[8..]).unwrap().0.to_ne_bytes(),
7579            [8, 9, 10, 11, 12, 13, 14, 15]
7580        );
7581        let suffix = AU64::mut_from_bytes(&mut buf.t[8..]).unwrap();
7582        suffix.0 = 0x0101010101010101;
7583        // The `[u8:9]` is a non-half size of the full buffer, which would catch
7584        // `from_prefix` having the same implementation as `from_suffix` (issues #506, #511).
7585        assert_eq!(
7586            <[u8; 9]>::ref_from_suffix(&buf.t[..]).unwrap(),
7587            (&[0, 1, 2, 3, 4, 5, 6][..], &[7u8, 1, 1, 1, 1, 1, 1, 1, 1])
7588        );
7589        let (prefix, suffix) = AU64::mut_from_suffix(&mut buf.t[1..]).unwrap();
7590        assert_eq!(prefix, &mut [1u8, 2, 3, 4, 5, 6, 7][..]);
7591        suffix.0 = 0x0202020202020202;
7592        let (prefix, suffix) = <[u8; 10]>::mut_from_suffix(&mut buf.t[..]).unwrap();
7593        assert_eq!(prefix, &mut [0u8, 1, 2, 3, 4, 5][..]);
7594        suffix[0] = 42;
7595        assert_eq!(
7596            <[u8; 9]>::ref_from_prefix(&buf.t[..]).unwrap(),
7597            (&[0u8, 1, 2, 3, 4, 5, 42, 7, 2], &[2u8, 2, 2, 2, 2, 2, 2][..])
7598        );
7599        <[u8; 2]>::mut_from_prefix(&mut buf.t[..]).unwrap().0[1] = 30;
7600        assert_eq!(buf.t, [0, 30, 2, 3, 4, 5, 42, 7, 2, 2, 2, 2, 2, 2, 2, 2]);
7601    }
7602
7603    #[test]
7604    fn test_ref_from_mut_from_bytes_error() {
7605        // Test `FromBytes::{ref_from_bytes, mut_from_bytes}{,_prefix,Suffix}`
7606        // error cases.
7607
7608        // Fail because the buffer is too large.
7609        let mut buf = Align::<[u8; 16], AU64>::default();
7610        // `buf.t` should be aligned to 8, so only the length check should fail.
7611        assert!(AU64::ref_from_bytes(&buf.t[..]).is_err());
7612        assert!(AU64::mut_from_bytes(&mut buf.t[..]).is_err());
7613        assert!(<[u8; 8]>::ref_from_bytes(&buf.t[..]).is_err());
7614        assert!(<[u8; 8]>::mut_from_bytes(&mut buf.t[..]).is_err());
7615
7616        // Fail because the buffer is too small.
7617        let mut buf = Align::<[u8; 4], AU64>::default();
7618        assert!(AU64::ref_from_bytes(&buf.t[..]).is_err());
7619        assert!(AU64::mut_from_bytes(&mut buf.t[..]).is_err());
7620        assert!(<[u8; 8]>::ref_from_bytes(&buf.t[..]).is_err());
7621        assert!(<[u8; 8]>::mut_from_bytes(&mut buf.t[..]).is_err());
7622        assert!(AU64::ref_from_prefix(&buf.t[..]).is_err());
7623        assert!(AU64::mut_from_prefix(&mut buf.t[..]).is_err());
7624        assert!(AU64::ref_from_suffix(&buf.t[..]).is_err());
7625        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_err());
7626        assert!(<[u8; 8]>::ref_from_prefix(&buf.t[..]).is_err());
7627        assert!(<[u8; 8]>::mut_from_prefix(&mut buf.t[..]).is_err());
7628        assert!(<[u8; 8]>::ref_from_suffix(&buf.t[..]).is_err());
7629        assert!(<[u8; 8]>::mut_from_suffix(&mut buf.t[..]).is_err());
7630
7631        // Fail because the alignment is insufficient.
7632        let mut buf = Align::<[u8; 13], AU64>::default();
7633        assert!(AU64::ref_from_bytes(&buf.t[1..]).is_err());
7634        assert!(AU64::mut_from_bytes(&mut buf.t[1..]).is_err());
7635        assert!(AU64::ref_from_bytes(&buf.t[1..]).is_err());
7636        assert!(AU64::mut_from_bytes(&mut buf.t[1..]).is_err());
7637        assert!(AU64::ref_from_prefix(&buf.t[1..]).is_err());
7638        assert!(AU64::mut_from_prefix(&mut buf.t[1..]).is_err());
7639        assert!(AU64::ref_from_suffix(&buf.t[..]).is_err());
7640        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_err());
7641    }
7642
7643    #[test]
7644    fn test_to_methods() {
7645        /// Run a series of tests by calling `IntoBytes` methods on `t`.
7646        ///
7647        /// `bytes` is the expected byte sequence returned from `t.as_bytes()`
7648        /// before `t` has been modified. `post_mutation` is the expected
7649        /// sequence returned from `t.as_bytes()` after `t.as_mut_bytes()[0]`
7650        /// has had its bits flipped (by applying `^= 0xFF`).
7651        ///
7652        /// `N` is the size of `t` in bytes.
7653        fn test<T: FromBytes + IntoBytes + Immutable + Debug + Eq + ?Sized, const N: usize>(
7654            t: &mut T,
7655            bytes: &[u8],
7656            post_mutation: &T,
7657        ) {
7658            // Test that we can access the underlying bytes, and that we get the
7659            // right bytes and the right number of bytes.
7660            assert_eq!(t.as_bytes(), bytes);
7661
7662            // Test that changes to the underlying byte slices are reflected in
7663            // the original object.
7664            t.as_mut_bytes()[0] ^= 0xFF;
7665            assert_eq!(t, post_mutation);
7666            t.as_mut_bytes()[0] ^= 0xFF;
7667
7668            // `write_to` rejects slices that are too small or too large.
7669            assert!(t.write_to(&mut vec![0; N - 1][..]).is_err());
7670            assert!(t.write_to(&mut vec![0; N + 1][..]).is_err());
7671
7672            // `write_to` works as expected.
7673            let mut bytes = [0; N];
7674            assert_eq!(t.write_to(&mut bytes[..]), Ok(()));
7675            assert_eq!(bytes, t.as_bytes());
7676
7677            // `write_to_prefix` rejects slices that are too small.
7678            assert!(t.write_to_prefix(&mut vec![0; N - 1][..]).is_err());
7679
7680            // `write_to_prefix` works with exact-sized slices.
7681            let mut bytes = [0; N];
7682            assert_eq!(t.write_to_prefix(&mut bytes[..]), Ok(()));
7683            assert_eq!(bytes, t.as_bytes());
7684
7685            // `write_to_prefix` works with too-large slices, and any bytes past
7686            // the prefix aren't modified.
7687            let mut too_many_bytes = vec![0; N + 1];
7688            too_many_bytes[N] = 123;
7689            assert_eq!(t.write_to_prefix(&mut too_many_bytes[..]), Ok(()));
7690            assert_eq!(&too_many_bytes[..N], t.as_bytes());
7691            assert_eq!(too_many_bytes[N], 123);
7692
7693            // `write_to_suffix` rejects slices that are too small.
7694            assert!(t.write_to_suffix(&mut vec![0; N - 1][..]).is_err());
7695
7696            // `write_to_suffix` works with exact-sized slices.
7697            let mut bytes = [0; N];
7698            assert_eq!(t.write_to_suffix(&mut bytes[..]), Ok(()));
7699            assert_eq!(bytes, t.as_bytes());
7700
7701            // `write_to_suffix` works with too-large slices, and any bytes
7702            // before the suffix aren't modified.
7703            let mut too_many_bytes = vec![0; N + 1];
7704            too_many_bytes[0] = 123;
7705            assert_eq!(t.write_to_suffix(&mut too_many_bytes[..]), Ok(()));
7706            assert_eq!(&too_many_bytes[1..], t.as_bytes());
7707            assert_eq!(too_many_bytes[0], 123);
7708        }
7709
7710        #[derive(Debug, Eq, PartialEq, FromBytes, IntoBytes, Immutable)]
7711        #[repr(C)]
7712        struct Foo {
7713            a: u32,
7714            b: Wrapping<u32>,
7715            c: Option<NonZeroU32>,
7716        }
7717
7718        let expected_bytes: Vec<u8> = if cfg!(target_endian = "little") {
7719            vec![1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]
7720        } else {
7721            vec![0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0]
7722        };
7723        let post_mutation_expected_a =
7724            if cfg!(target_endian = "little") { 0x00_00_00_FE } else { 0xFF_00_00_01 };
7725        test::<_, 12>(
7726            &mut Foo { a: 1, b: Wrapping(2), c: None },
7727            expected_bytes.as_bytes(),
7728            &Foo { a: post_mutation_expected_a, b: Wrapping(2), c: None },
7729        );
7730        test::<_, 3>(
7731            Unsized::from_mut_slice(&mut [1, 2, 3]),
7732            &[1, 2, 3],
7733            Unsized::from_mut_slice(&mut [0xFE, 2, 3]),
7734        );
7735    }
7736
7737    #[test]
7738    fn test_array() {
7739        #[derive(FromBytes, IntoBytes, Immutable)]
7740        #[repr(C)]
7741        struct Foo {
7742            a: [u16; 33],
7743        }
7744
7745        let foo = Foo { a: [0xFFFF; 33] };
7746        let expected = [0xFFu8; 66];
7747        assert_eq!(foo.as_bytes(), &expected[..]);
7748    }
7749
7750    #[test]
7751    fn test_new_zeroed() {
7752        assert!(!bool::new_zeroed());
7753        assert_eq!(u64::new_zeroed(), 0);
7754        // This test exists in order to exercise unsafe code, especially when
7755        // running under Miri.
7756        #[allow(clippy::unit_cmp)]
7757        {
7758            assert_eq!(<()>::new_zeroed(), ());
7759        }
7760    }
7761
7762    #[test]
7763    fn test_transparent_packed_generic_struct() {
7764        #[derive(IntoBytes, FromBytes, Unaligned)]
7765        #[repr(transparent)]
7766        #[allow(dead_code)] // We never construct this type
7767        struct Foo<T> {
7768            _t: T,
7769            _phantom: PhantomData<()>,
7770        }
7771
7772        assert_impl_all!(Foo<u32>: FromZeros, FromBytes, IntoBytes);
7773        assert_impl_all!(Foo<u8>: Unaligned);
7774
7775        #[derive(IntoBytes, FromBytes, Unaligned)]
7776        #[repr(C, packed)]
7777        #[allow(dead_code)] // We never construct this type
7778        struct Bar<T, U> {
7779            _t: T,
7780            _u: U,
7781        }
7782
7783        assert_impl_all!(Bar<u8, AU64>: FromZeros, FromBytes, IntoBytes, Unaligned);
7784    }
7785
7786    #[cfg(feature = "alloc")]
7787    mod alloc {
7788        use super::*;
7789
7790        #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
7791        #[test]
7792        fn test_extend_vec_zeroed() {
7793            // Test extending when there is an existing allocation.
7794            let mut v = vec![100u16, 200, 300];
7795            FromZeros::extend_vec_zeroed(&mut v, 3).unwrap();
7796            assert_eq!(v.len(), 6);
7797            assert_eq!(&*v, &[100, 200, 300, 0, 0, 0]);
7798            drop(v);
7799
7800            // Test extending when there is no existing allocation.
7801            let mut v: Vec<u64> = Vec::new();
7802            FromZeros::extend_vec_zeroed(&mut v, 3).unwrap();
7803            assert_eq!(v.len(), 3);
7804            assert_eq!(&*v, &[0, 0, 0]);
7805            drop(v);
7806        }
7807
7808        #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
7809        #[test]
7810        fn test_extend_vec_zeroed_zst() {
7811            // Test extending when there is an existing (fake) allocation.
7812            let mut v = vec![(), (), ()];
7813            <()>::extend_vec_zeroed(&mut v, 3).unwrap();
7814            assert_eq!(v.len(), 6);
7815            assert_eq!(&*v, &[(), (), (), (), (), ()]);
7816            drop(v);
7817
7818            // Test extending when there is no existing (fake) allocation.
7819            let mut v: Vec<()> = Vec::new();
7820            <()>::extend_vec_zeroed(&mut v, 3).unwrap();
7821            assert_eq!(&*v, &[(), (), ()]);
7822            drop(v);
7823        }
7824
7825        #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
7826        #[test]
7827        fn test_insert_vec_zeroed() {
7828            // Insert at start (no existing allocation).
7829            let mut v: Vec<u64> = Vec::new();
7830            u64::insert_vec_zeroed(&mut v, 0, 2).unwrap();
7831            assert_eq!(v.len(), 2);
7832            assert_eq!(&*v, &[0, 0]);
7833            drop(v);
7834
7835            // Insert at start.
7836            let mut v = vec![100u64, 200, 300];
7837            u64::insert_vec_zeroed(&mut v, 0, 2).unwrap();
7838            assert_eq!(v.len(), 5);
7839            assert_eq!(&*v, &[0, 0, 100, 200, 300]);
7840            drop(v);
7841
7842            // Insert at middle.
7843            let mut v = vec![100u64, 200, 300];
7844            u64::insert_vec_zeroed(&mut v, 1, 1).unwrap();
7845            assert_eq!(v.len(), 4);
7846            assert_eq!(&*v, &[100, 0, 200, 300]);
7847            drop(v);
7848
7849            // Insert at end.
7850            let mut v = vec![100u64, 200, 300];
7851            u64::insert_vec_zeroed(&mut v, 3, 1).unwrap();
7852            assert_eq!(v.len(), 4);
7853            assert_eq!(&*v, &[100, 200, 300, 0]);
7854            drop(v);
7855        }
7856
7857        #[cfg(not(no_zerocopy_panic_in_const_and_vec_try_reserve_1_57_0))]
7858        #[test]
7859        fn test_insert_vec_zeroed_zst() {
7860            // Insert at start (no existing fake allocation).
7861            let mut v: Vec<()> = Vec::new();
7862            <()>::insert_vec_zeroed(&mut v, 0, 2).unwrap();
7863            assert_eq!(v.len(), 2);
7864            assert_eq!(&*v, &[(), ()]);
7865            drop(v);
7866
7867            // Insert at start.
7868            let mut v = vec![(), (), ()];
7869            <()>::insert_vec_zeroed(&mut v, 0, 2).unwrap();
7870            assert_eq!(v.len(), 5);
7871            assert_eq!(&*v, &[(), (), (), (), ()]);
7872            drop(v);
7873
7874            // Insert at middle.
7875            let mut v = vec![(), (), ()];
7876            <()>::insert_vec_zeroed(&mut v, 1, 1).unwrap();
7877            assert_eq!(v.len(), 4);
7878            assert_eq!(&*v, &[(), (), (), ()]);
7879            drop(v);
7880
7881            // Insert at end.
7882            let mut v = vec![(), (), ()];
7883            <()>::insert_vec_zeroed(&mut v, 3, 1).unwrap();
7884            assert_eq!(v.len(), 4);
7885            assert_eq!(&*v, &[(), (), (), ()]);
7886            drop(v);
7887        }
7888
7889        #[test]
7890        fn test_new_box_zeroed() {
7891            assert_eq!(u64::new_box_zeroed(), Ok(Box::new(0)));
7892        }
7893
7894        #[test]
7895        fn test_new_box_zeroed_array() {
7896            drop(<[u32; 0x1000]>::new_box_zeroed());
7897        }
7898
7899        #[test]
7900        fn test_new_box_zeroed_zst() {
7901            // This test exists in order to exercise unsafe code, especially
7902            // when running under Miri.
7903            #[allow(clippy::unit_cmp)]
7904            {
7905                assert_eq!(<()>::new_box_zeroed(), Ok(Box::new(())));
7906            }
7907        }
7908
7909        #[test]
7910        fn test_new_box_zeroed_with_elems() {
7911            let mut s: Box<[u64]> = <[u64]>::new_box_zeroed_with_elems(3).unwrap();
7912            assert_eq!(s.len(), 3);
7913            assert_eq!(&*s, &[0, 0, 0]);
7914            s[1] = 3;
7915            assert_eq!(&*s, &[0, 3, 0]);
7916        }
7917
7918        #[test]
7919        fn test_new_box_zeroed_with_elems_empty() {
7920            let s: Box<[u64]> = <[u64]>::new_box_zeroed_with_elems(0).unwrap();
7921            assert_eq!(s.len(), 0);
7922        }
7923
7924        #[test]
7925        fn test_new_box_zeroed_with_elems_zst() {
7926            let mut s: Box<[()]> = <[()]>::new_box_zeroed_with_elems(3).unwrap();
7927            assert_eq!(s.len(), 3);
7928            assert!(s.get(10).is_none());
7929            // This test exists in order to exercise unsafe code, especially
7930            // when running under Miri.
7931            #[allow(clippy::unit_cmp)]
7932            {
7933                assert_eq!(s[1], ());
7934            }
7935            s[2] = ();
7936        }
7937
7938        #[test]
7939        fn test_new_box_zeroed_with_elems_zst_empty() {
7940            let s: Box<[()]> = <[()]>::new_box_zeroed_with_elems(0).unwrap();
7941            assert_eq!(s.len(), 0);
7942        }
7943
7944        #[test]
7945        fn new_box_zeroed_with_elems_errors() {
7946            assert_eq!(<[u16]>::new_box_zeroed_with_elems(usize::MAX), Err(AllocError));
7947
7948            let max = <usize as core::convert::TryFrom<_>>::try_from(isize::MAX).unwrap();
7949            assert_eq!(
7950                <[u16]>::new_box_zeroed_with_elems((max / mem::size_of::<u16>()) + 1),
7951                Err(AllocError)
7952            );
7953        }
7954    }
7955
7956    #[test]
7957    #[allow(deprecated)]
7958    fn test_deprecated_from_bytes() {
7959        let val = 0u32;
7960        let bytes = val.as_bytes();
7961
7962        assert!(u32::ref_from(bytes).is_some());
7963        // mut_from needs mut bytes
7964        let mut val = 0u32;
7965        let mut_bytes = val.as_mut_bytes();
7966        assert!(u32::mut_from(mut_bytes).is_some());
7967
7968        assert!(u32::read_from(bytes).is_some());
7969
7970        let (slc, rest) = <u32>::slice_from_prefix(bytes, 0).unwrap();
7971        assert!(slc.is_empty());
7972        assert_eq!(rest.len(), 4);
7973
7974        let (rest, slc) = <u32>::slice_from_suffix(bytes, 0).unwrap();
7975        assert!(slc.is_empty());
7976        assert_eq!(rest.len(), 4);
7977
7978        let (slc, rest) = <u32>::mut_slice_from_prefix(mut_bytes, 0).unwrap();
7979        assert!(slc.is_empty());
7980        assert_eq!(rest.len(), 4);
7981
7982        let (rest, slc) = <u32>::mut_slice_from_suffix(mut_bytes, 0).unwrap();
7983        assert!(slc.is_empty());
7984        assert_eq!(rest.len(), 4);
7985    }
7986
7987    #[test]
7988    fn test_ref_from_prefix_suffix_typed_source() {
7989        #[derive(IntoBytes, Immutable)]
7990        #[repr(transparent)]
7991        struct Source<T: ?Sized>(T);
7992
7993        fn check<S: IntoBytes + Immutable + ?Sized>(source: &S) {
7994            let bytes = source.as_bytes();
7995            assert_eq!(bytes.len(), 4);
7996
7997            for cast_type in [CastType::Prefix, CastType::Suffix] {
7998                let (expected, expected_rest) = match cast_type {
7999                    CastType::Prefix => (&bytes[..3], &bytes[3..]),
8000                    CastType::Suffix => (&bytes[1..], &bytes[..1]),
8001                };
8002                for meta in [None, Some(1)] {
8003                    let (value, rest) =
8004                        ref_from_prefix_suffix::<_, [[u8; 3]]>(source, meta, cast_type).unwrap();
8005                    assert_eq!(value, &[expected]);
8006                    assert!(ptr::eq(value.as_bytes(), expected));
8007                    assert!(ptr::eq(rest, expected_rest));
8008                }
8009
8010                let err =
8011                    ref_from_prefix_suffix::<_, [u8; 5]>(source, None, cast_type).unwrap_err();
8012                assert!(matches!(err, CastError::Size(_)));
8013                assert!(ptr::eq(err.into_src(), source));
8014
8015                let err =
8016                    ref_from_prefix_suffix::<_, [u8]>(source, Some(5), cast_type).unwrap_err();
8017                assert!(matches!(err, CastError::Size(_)));
8018                assert!(ptr::eq(err.into_src(), source));
8019            }
8020        }
8021
8022        check(&Source([0x0102u16, 0x0304]));
8023        let source = Source([false, true, false, true]);
8024        let source: &Source<[bool]> = &source;
8025        check(source);
8026    }
8027
8028    #[test]
8029    fn test_ref_from_prefix_suffix_typed_source_alignment_error() {
8030        let storage = Align::<[bool; 9], AU64>::new([false; 9]);
8031        for cast_type in [CastType::Prefix, CastType::Suffix] {
8032            let source = match cast_type {
8033                CastType::Prefix => &storage.t[1..],
8034                CastType::Suffix => &storage.t[..],
8035            };
8036            let err = ref_from_prefix_suffix::<_, AU64>(source, None, cast_type).unwrap_err();
8037            assert!(matches!(err, CastError::Alignment(_)));
8038            let recovered: &[bool] = err.into_src();
8039            assert!(ptr::eq(recovered, source));
8040
8041            let err = try_ref_from_prefix_suffix::<_, AU64>(source, cast_type, None).unwrap_err();
8042            assert!(matches!(err, TryCastError::Alignment(_)));
8043            let recovered: &[bool] = err.into_src();
8044            assert!(ptr::eq(recovered, source));
8045        }
8046    }
8047
8048    #[test]
8049    fn test_try_ref_from_prefix_suffix_typed_source() {
8050        #[derive(IntoBytes, Immutable)]
8051        #[repr(transparent)]
8052        struct Source<T: ?Sized>(T);
8053
8054        fn check<S: IntoBytes + Immutable + ?Sized>(source: &S) {
8055            let bytes = source.as_bytes();
8056            assert_eq!(bytes, [0, 1, 0, 1]);
8057
8058            for cast_type in [CastType::Prefix, CastType::Suffix] {
8059                let (expected, expected_rest) = match cast_type {
8060                    CastType::Prefix => (&bytes[..3], &bytes[3..]),
8061                    CastType::Suffix => (&bytes[1..], &bytes[..1]),
8062                };
8063                for meta in [None, Some(1)] {
8064                    let (value, rest) =
8065                        try_ref_from_prefix_suffix::<_, [[bool; 3]]>(source, cast_type, meta)
8066                            .unwrap();
8067                    assert_eq!(value.as_bytes(), expected);
8068                    assert!(ptr::eq(value.as_bytes(), expected));
8069                    assert!(ptr::eq(rest, expected_rest));
8070                }
8071
8072                let err = try_ref_from_prefix_suffix::<_, [bool; 5]>(source, cast_type, None)
8073                    .unwrap_err();
8074                assert!(matches!(err, TryCastError::Size(_)));
8075                assert!(ptr::eq(err.into_src(), source));
8076
8077                let err = try_ref_from_prefix_suffix::<_, [bool]>(source, cast_type, Some(5))
8078                    .unwrap_err();
8079                assert!(matches!(err, TryCastError::Size(_)));
8080                assert!(ptr::eq(err.into_src(), source));
8081            }
8082        }
8083
8084        check(&Source([u16::from_ne_bytes([0, 1]); 2]));
8085        let source = Source([false, true, false, true]);
8086        let source: &Source<[bool]> = &source;
8087        check(source);
8088    }
8089
8090    #[test]
8091    fn test_try_ref_from_prefix_suffix_typed_source_validity_error() {
8092        fn check<S: IntoBytes + Immutable + ?Sized>(source: &S) {
8093            for cast_type in [CastType::Prefix, CastType::Suffix] {
8094                let err =
8095                    try_ref_from_prefix_suffix::<_, bool>(source, cast_type, None).unwrap_err();
8096                assert!(matches!(err, TryCastError::Validity(_)));
8097                assert!(ptr::eq(err.into_src(), source));
8098
8099                for meta in [None, Some(1)] {
8100                    let err = try_ref_from_prefix_suffix::<_, [bool]>(source, cast_type, meta)
8101                        .unwrap_err();
8102                    assert!(matches!(err, TryCastError::Validity(_)));
8103                    assert!(ptr::eq(err.into_src(), source));
8104                }
8105            }
8106        }
8107
8108        let source = [u16::from_ne_bytes([2, 2]); 2];
8109        check(&source);
8110        check(&source[..]);
8111        check(source.as_bytes());
8112    }
8113
8114    #[test]
8115    fn test_try_ref_from_prefix_suffix() {
8116        use crate::util::testutil::Align;
8117        let bytes = &Align::<[u8; 4], u32>::new([0u8; 4]).t[..];
8118        let (r, rest): (&u32, &[u8]) = u32::try_ref_from_prefix(bytes).unwrap();
8119        assert_eq!(*r, 0);
8120        assert_eq!(rest.len(), 0);
8121
8122        let (rest, r): (&[u8], &u32) = u32::try_ref_from_suffix(bytes).unwrap();
8123        assert_eq!(*r, 0);
8124        assert_eq!(rest.len(), 0);
8125    }
8126
8127    #[test]
8128    fn test_raw_dangling() {
8129        use crate::util::AsAddress;
8130        let ptr: NonNull<u32> = u32::raw_dangling();
8131        assert_eq!(AsAddress::addr(ptr), 1);
8132
8133        let ptr: NonNull<[u32]> = <[u32]>::raw_dangling();
8134        assert_eq!(AsAddress::addr(ptr), 1);
8135    }
8136
8137    #[test]
8138    fn test_try_ref_from_prefix_with_elems() {
8139        use crate::util::testutil::Align;
8140        let bytes = &Align::<[u8; 8], u32>::new([0u8; 8]).t[..];
8141        let (r, rest): (&[u32], &[u8]) = <[u32]>::try_ref_from_prefix_with_elems(bytes, 2).unwrap();
8142        assert_eq!(r.len(), 2);
8143        assert_eq!(rest.len(), 0);
8144    }
8145
8146    #[test]
8147    fn test_try_ref_from_suffix_with_elems() {
8148        use crate::util::testutil::Align;
8149        let bytes = &Align::<[u8; 8], u32>::new([0u8; 8]).t[..];
8150        let (rest, r): (&[u8], &[u32]) = <[u32]>::try_ref_from_suffix_with_elems(bytes, 2).unwrap();
8151        assert_eq!(r.len(), 2);
8152        assert_eq!(rest.len(), 0);
8153    }
8154}