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