Skip to main content

zerocopy/
lib.rs

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