Skip to main content

zerocopy/
lib.rs

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