Coverage Report

Created: 2026-01-22 07:28

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