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