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