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