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