Coverage Report

Created: 2026-08-13 08:17

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