Coverage Report

Created: 2026-06-02 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.7.34/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
//   ./generate-readme.sh > README.md
14
15
//! *<span style="font-size: 100%; color:grey;">Want to help improve zerocopy?
16
//! Fill out our [user survey][user-survey]!</span>*
17
//!
18
//! ***<span style="font-size: 140%">Fast, safe, <span
19
//! style="color:red;">compile error</span>. Pick two.</span>***
20
//!
21
//! Zerocopy makes zero-cost memory manipulation effortless. We write `unsafe`
22
//! so you don't have to.
23
//!
24
//! # Overview
25
//!
26
//! Zerocopy provides four core marker traits, each of which can be derived
27
//! (e.g., `#[derive(FromZeroes)]`):
28
//! - [`FromZeroes`] indicates that a sequence of zero bytes represents a valid
29
//!   instance of a type
30
//! - [`FromBytes`] indicates that a type may safely be converted from an
31
//!   arbitrary byte sequence
32
//! - [`AsBytes`] indicates that a type may safely be converted *to* a byte
33
//!   sequence
34
//! - [`Unaligned`] indicates that a type's alignment requirement is 1
35
//!
36
//! Types which implement a subset of these traits can then be converted to/from
37
//! byte sequences with little to no runtime overhead.
38
//!
39
//! Zerocopy also provides byte-order aware integer types that support these
40
//! conversions; see the [`byteorder`] module. These types are especially useful
41
//! for network parsing.
42
//!
43
//! [user-survey]: https://docs.google.com/forms/d/e/1FAIpQLSdzBNTN9tzwsmtyZxRFNL02K36IWCdHWW2ZBckyQS2xiO3i8Q/viewform?usp=published_options
44
//!
45
//! # Cargo Features
46
//!
47
//! - **`alloc`**   
48
//!   By default, `zerocopy` is `no_std`. When the `alloc` feature is enabled,
49
//!   the `alloc` crate is added as a dependency, and some allocation-related
50
//!   functionality is added.
51
//!
52
//! - **`byteorder`** (enabled by default)   
53
//!   Adds the [`byteorder`] module and a dependency on the `byteorder` crate.
54
//!   The `byteorder` module provides byte order-aware equivalents of the
55
//!   multi-byte primitive numerical types. Unlike their primitive equivalents,
56
//!   the types in this module have no alignment requirement and support byte
57
//!   order conversions. This can be useful in handling file formats, network
58
//!   packet layouts, etc which don't provide alignment guarantees and which may
59
//!   use a byte order different from that of the execution platform.
60
//!
61
//! - **`derive`**   
62
//!   Provides derives for the core marker traits via the `zerocopy-derive`
63
//!   crate. These derives are re-exported from `zerocopy`, so it is not
64
//!   necessary to depend on `zerocopy-derive` directly.   
65
//!
66
//!   However, you may experience better compile times if you instead directly
67
//!   depend on both `zerocopy` and `zerocopy-derive` in your `Cargo.toml`,
68
//!   since doing so will allow Rust to compile these crates in parallel. To do
69
//!   so, do *not* enable the `derive` feature, and list both dependencies in
70
//!   your `Cargo.toml` with the same leading non-zero version number; e.g:
71
//!
72
//!   ```toml
73
//!   [dependencies]
74
//!   zerocopy = "0.X"
75
//!   zerocopy-derive = "0.X"
76
//!   ```
77
//!
78
//! - **`simd`**   
79
//!   When the `simd` feature is enabled, `FromZeroes`, `FromBytes`, and
80
//!   `AsBytes` impls are emitted for all stable SIMD types which exist on the
81
//!   target platform. Note that the layout of SIMD types is not yet stabilized,
82
//!   so these impls may be removed in the future if layout changes make them
83
//!   invalid. For more information, see the Unsafe Code Guidelines Reference
84
//!   page on the [layout of packed SIMD vectors][simd-layout].
85
//!
86
//! - **`simd-nightly`**   
87
//!   Enables the `simd` feature and adds support for SIMD types which are only
88
//!   available on nightly. Since these types are unstable, support for any type
89
//!   may be removed at any point in the future.
90
//!
91
//! [simd-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
92
//!
93
//! # Security Ethos
94
//!
95
//! Zerocopy is expressly designed for use in security-critical contexts. We
96
//! strive to ensure that that zerocopy code is sound under Rust's current
97
//! memory model, and *any future memory model*. We ensure this by:
98
//! - **...not 'guessing' about Rust's semantics.**   
99
//!   We annotate `unsafe` code with a precise rationale for its soundness that
100
//!   cites a relevant section of Rust's official documentation. When Rust's
101
//!   documented semantics are unclear, we work with the Rust Operational
102
//!   Semantics Team to clarify Rust's documentation.
103
//! - **...rigorously testing our implementation.**   
104
//!   We run tests using [Miri], ensuring that zerocopy is sound across a wide
105
//!   array of supported target platforms of varying endianness and pointer
106
//!   width, and across both current and experimental memory models of Rust.
107
//! - **...formally proving the correctness of our implementation.**   
108
//!   We apply formal verification tools like [Kani][kani] to prove zerocopy's
109
//!   correctness.
110
//!
111
//! For more information, see our full [soundness policy].
112
//!
113
//! [Miri]: https://github.com/rust-lang/miri
114
//! [Kani]: https://github.com/model-checking/kani
115
//! [soundness policy]: https://github.com/google/zerocopy/blob/main/POLICIES.md#soundness
116
//!
117
//! # Relationship to Project Safe Transmute
118
//!
119
//! [Project Safe Transmute] is an official initiative of the Rust Project to
120
//! develop language-level support for safer transmutation. The Project consults
121
//! with crates like zerocopy to identify aspects of safer transmutation that
122
//! would benefit from compiler support, and has developed an [experimental,
123
//! compiler-supported analysis][mcp-transmutability] which determines whether,
124
//! for a given type, any value of that type may be soundly transmuted into
125
//! another type. Once this functionality is sufficiently mature, zerocopy
126
//! intends to replace its internal transmutability analysis (implemented by our
127
//! custom derives) with the compiler-supported one. This change will likely be
128
//! an implementation detail that is invisible to zerocopy's users.
129
//!
130
//! Project Safe Transmute will not replace the need for most of zerocopy's
131
//! higher-level abstractions. The experimental compiler analysis is a tool for
132
//! checking the soundness of `unsafe` code, not a tool to avoid writing
133
//! `unsafe` code altogether. For the foreseeable future, crates like zerocopy
134
//! will still be required in order to provide higher-level abstractions on top
135
//! of the building block provided by Project Safe Transmute.
136
//!
137
//! [Project Safe Transmute]: https://rust-lang.github.io/rfcs/2835-project-safe-transmute.html
138
//! [mcp-transmutability]: https://github.com/rust-lang/compiler-team/issues/411
139
//!
140
//! # MSRV
141
//!
142
//! See our [MSRV policy].
143
//!
144
//! [MSRV policy]: https://github.com/google/zerocopy/blob/main/POLICIES.md#msrv
145
//!
146
//! # Changelog
147
//!
148
//! Zerocopy uses [GitHub Releases].
149
//!
150
//! [GitHub Releases]: https://github.com/google/zerocopy/releases
151
152
// Sometimes we want to use lints which were added after our MSRV.
153
// `unknown_lints` is `warn` by default and we deny warnings in CI, so without
154
// this attribute, any unknown lint would cause a CI failure when testing with
155
// our MSRV.
156
//
157
// TODO(#1201): Remove `unexpected_cfgs`
158
#![allow(unknown_lints, non_local_definitions, unexpected_cfgs)]
159
#![deny(renamed_and_removed_lints)]
160
#![deny(
161
    anonymous_parameters,
162
    deprecated_in_future,
163
    late_bound_lifetime_arguments,
164
    missing_copy_implementations,
165
    missing_debug_implementations,
166
    missing_docs,
167
    path_statements,
168
    patterns_in_fns_without_body,
169
    rust_2018_idioms,
170
    trivial_numeric_casts,
171
    unreachable_pub,
172
    unsafe_op_in_unsafe_fn,
173
    unused_extern_crates,
174
    unused_qualifications,
175
    variant_size_differences
176
)]
177
#![cfg_attr(
178
    __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
179
    deny(fuzzy_provenance_casts, lossy_provenance_casts)
180
)]
181
#![deny(
182
    clippy::all,
183
    clippy::alloc_instead_of_core,
184
    clippy::arithmetic_side_effects,
185
    clippy::as_underscore,
186
    clippy::assertions_on_result_states,
187
    clippy::as_conversions,
188
    clippy::correctness,
189
    clippy::dbg_macro,
190
    clippy::decimal_literal_representation,
191
    clippy::get_unwrap,
192
    clippy::indexing_slicing,
193
    clippy::missing_inline_in_public_items,
194
    clippy::missing_safety_doc,
195
    clippy::obfuscated_if_else,
196
    clippy::perf,
197
    clippy::print_stdout,
198
    clippy::std_instead_of_core,
199
    clippy::style,
200
    clippy::suspicious,
201
    clippy::todo,
202
    clippy::undocumented_unsafe_blocks,
203
    clippy::unimplemented,
204
    clippy::unnested_or_patterns,
205
    clippy::unwrap_used,
206
    clippy::use_debug
207
)]
208
#![deny(
209
    rustdoc::bare_urls,
210
    rustdoc::broken_intra_doc_links,
211
    rustdoc::invalid_codeblock_attributes,
212
    rustdoc::invalid_html_tags,
213
    rustdoc::invalid_rust_codeblocks,
214
    rustdoc::missing_crate_level_docs,
215
    rustdoc::private_intra_doc_links
216
)]
217
// In test code, it makes sense to weight more heavily towards concise, readable
218
// code over correct or debuggable code.
219
#![cfg_attr(any(test, kani), allow(
220
    // In tests, you get line numbers and have access to source code, so panic
221
    // messages are less important. You also often unwrap a lot, which would
222
    // make expect'ing instead very verbose.
223
    clippy::unwrap_used,
224
    // In tests, there's no harm to "panic risks" - the worst that can happen is
225
    // that your test will fail, and you'll fix it. By contrast, panic risks in
226
    // production code introduce the possibly of code panicking unexpectedly "in
227
    // the field".
228
    clippy::arithmetic_side_effects,
229
    clippy::indexing_slicing,
230
))]
231
#![cfg_attr(not(test), no_std)]
232
#![cfg_attr(
233
    all(feature = "simd-nightly", any(target_arch = "x86", target_arch = "x86_64")),
234
    feature(stdarch_x86_avx512)
235
)]
236
#![cfg_attr(
237
    all(feature = "simd-nightly", target_arch = "arm"),
238
    feature(stdarch_arm_dsp, stdarch_arm_neon_intrinsics)
239
)]
240
#![cfg_attr(
241
    all(feature = "simd-nightly", any(target_arch = "powerpc", target_arch = "powerpc64")),
242
    feature(stdarch_powerpc)
243
)]
244
#![cfg_attr(doc_cfg, feature(doc_cfg))]
245
#![cfg_attr(
246
    __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS,
247
    feature(layout_for_ptr, strict_provenance)
248
)]
249
250
// This is a hack to allow zerocopy-derive derives to work in this crate. They
251
// assume that zerocopy is linked as an extern crate, so they access items from
252
// it as `zerocopy::Xxx`. This makes that still work.
253
#[cfg(any(feature = "derive", test))]
254
extern crate self as zerocopy;
255
256
#[macro_use]
257
mod macros;
258
259
#[cfg(feature = "byteorder")]
260
#[cfg_attr(doc_cfg, doc(cfg(feature = "byteorder")))]
261
pub mod byteorder;
262
#[doc(hidden)]
263
pub mod macro_util;
264
mod post_monomorphization_compile_fail_tests;
265
mod util;
266
// TODO(#252): If we make this pub, come up with a better name.
267
mod wrappers;
268
269
#[cfg(feature = "byteorder")]
270
#[cfg_attr(doc_cfg, doc(cfg(feature = "byteorder")))]
271
pub use crate::byteorder::*;
272
pub use crate::wrappers::*;
273
274
#[cfg(any(feature = "derive", test))]
275
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
276
pub use zerocopy_derive::Unaligned;
277
278
// `pub use` separately here so that we can mark it `#[doc(hidden)]`.
279
//
280
// TODO(#29): Remove this or add a doc comment.
281
#[cfg(any(feature = "derive", test))]
282
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
283
#[doc(hidden)]
284
pub use zerocopy_derive::KnownLayout;
285
286
use core::{
287
    cell::{self, RefMut},
288
    cmp::Ordering,
289
    fmt::{self, Debug, Display, Formatter},
290
    hash::Hasher,
291
    marker::PhantomData,
292
    mem::{self, ManuallyDrop, MaybeUninit},
293
    num::{
294
        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
295
        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
296
    },
297
    ops::{Deref, DerefMut},
298
    ptr::{self, NonNull},
299
    slice,
300
};
301
302
#[cfg(feature = "alloc")]
303
extern crate alloc;
304
#[cfg(feature = "alloc")]
305
use alloc::{boxed::Box, vec::Vec};
306
307
#[cfg(any(feature = "alloc", kani))]
308
use core::alloc::Layout;
309
310
// Used by `TryFromBytes::is_bit_valid`.
311
#[doc(hidden)]
312
pub use crate::util::ptr::Ptr;
313
314
// For each polyfill, as soon as the corresponding feature is stable, the
315
// polyfill import will be unused because method/function resolution will prefer
316
// the inherent method/function over a trait method/function. Thus, we suppress
317
// the `unused_imports` warning.
318
//
319
// See the documentation on `util::polyfills` for more information.
320
#[allow(unused_imports)]
321
use crate::util::polyfills::NonNullExt as _;
322
323
#[rustversion::nightly]
324
#[cfg(all(test, not(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)))]
325
const _: () = {
326
    #[deprecated = "some tests may be skipped due to missing RUSTFLAGS=\"--cfg __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS\""]
327
    const _WARNING: () = ();
328
    #[warn(deprecated)]
329
    _WARNING
330
};
331
332
/// The target pointer width, counted in bits.
333
const POINTER_WIDTH_BITS: usize = mem::size_of::<usize>() * 8;
334
335
/// The layout of a type which might be dynamically-sized.
336
///
337
/// `DstLayout` describes the layout of sized types, slice types, and "slice
338
/// DSTs" - ie, those that are known by the type system to have a trailing slice
339
/// (as distinguished from `dyn Trait` types - such types *might* have a
340
/// trailing slice type, but the type system isn't aware of it).
341
///
342
/// # Safety
343
///
344
/// Unlike [`core::alloc::Layout`], `DstLayout` is only used to describe full
345
/// Rust types - ie, those that satisfy the layout requirements outlined by
346
/// [the reference]. Callers may assume that an instance of `DstLayout`
347
/// satisfies any conditions imposed on Rust types by the reference.
348
///
349
/// If `layout: DstLayout` describes a type, `T`, then it is guaranteed that:
350
/// - `layout.align` is equal to `T`'s alignment
351
/// - If `layout.size_info` is `SizeInfo::Sized { size }`, then `T: Sized` and
352
///   `size_of::<T>() == size`
353
/// - If `layout.size_info` is `SizeInfo::SliceDst(slice_layout)`, then
354
///   - `T` is a slice DST
355
/// - The `size` of an instance of `T` with `elems` trailing slice elements is
356
///   equal to `slice_layout.offset + slice_layout.elem_size * elems` rounded up
357
///   to the nearest multiple of `layout.align`. Any bytes in the range
358
///   `[slice_layout.offset + slice_layout.elem_size * elems, size)` are padding
359
///   and must not be assumed to be initialized.
360
///
361
/// [the reference]: https://doc.rust-lang.org/reference/type-layout.html
362
#[doc(hidden)]
363
#[allow(missing_debug_implementations, missing_copy_implementations)]
364
#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
365
pub struct DstLayout {
366
    align: NonZeroUsize,
367
    size_info: SizeInfo,
368
}
369
370
#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
371
enum SizeInfo<E = usize> {
372
    Sized { _size: usize },
373
    SliceDst(TrailingSliceLayout<E>),
374
}
375
376
#[cfg_attr(any(kani, test), derive(Copy, Clone, Debug, PartialEq, Eq))]
377
struct TrailingSliceLayout<E = usize> {
378
    // The offset of the first byte of the trailing slice field. Note that this
379
    // is NOT the same as the minimum size of the type. For example, consider
380
    // the following type:
381
    //
382
    //   struct Foo {
383
    //       a: u16,
384
    //       b: u8,
385
    //       c: [u8],
386
    //   }
387
    //
388
    // In `Foo`, `c` is at byte offset 3. When `c.len() == 0`, `c` is followed
389
    // by a padding byte.
390
    _offset: usize,
391
    // The size of the element type of the trailing slice field.
392
    _elem_size: E,
393
}
394
395
impl SizeInfo {
396
    /// Attempts to create a `SizeInfo` from `Self` in which `elem_size` is a
397
    /// `NonZeroUsize`. If `elem_size` is 0, returns `None`.
398
    #[allow(unused)]
399
0
    const fn try_to_nonzero_elem_size(&self) -> Option<SizeInfo<NonZeroUsize>> {
400
0
        Some(match *self {
401
0
            SizeInfo::Sized { _size } => SizeInfo::Sized { _size },
402
0
            SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size }) => {
403
0
                if let Some(_elem_size) = NonZeroUsize::new(_elem_size) {
404
0
                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size })
405
                } else {
406
0
                    return None;
407
                }
408
            }
409
        })
410
0
    }
411
}
412
413
#[doc(hidden)]
414
#[derive(Copy, Clone)]
415
#[cfg_attr(test, derive(Debug))]
416
#[allow(missing_debug_implementations)]
417
pub enum _CastType {
418
    _Prefix,
419
    _Suffix,
420
}
421
422
impl DstLayout {
423
    /// The minimum possible alignment of a type.
424
    const MIN_ALIGN: NonZeroUsize = match NonZeroUsize::new(1) {
425
        Some(min_align) => min_align,
426
        None => unreachable!(),
427
    };
428
429
    /// The maximum theoretic possible alignment of a type.
430
    ///
431
    /// For compatibility with future Rust versions, this is defined as the
432
    /// maximum power-of-two that fits into a `usize`. See also
433
    /// [`DstLayout::CURRENT_MAX_ALIGN`].
434
    const THEORETICAL_MAX_ALIGN: NonZeroUsize =
435
        match NonZeroUsize::new(1 << (POINTER_WIDTH_BITS - 1)) {
436
            Some(max_align) => max_align,
437
            None => unreachable!(),
438
        };
439
440
    /// The current, documented max alignment of a type \[1\].
441
    ///
442
    /// \[1\] Per <https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers>:
443
    ///
444
    ///   The alignment value must be a power of two from 1 up to
445
    ///   2<sup>29</sup>.
446
    #[cfg(not(kani))]
447
    const CURRENT_MAX_ALIGN: NonZeroUsize = match NonZeroUsize::new(1 << 28) {
448
        Some(max_align) => max_align,
449
        None => unreachable!(),
450
    };
451
452
    /// Constructs a `DstLayout` for a zero-sized type with `repr_align`
453
    /// alignment (or 1). If `repr_align` is provided, then it must be a power
454
    /// of two.
455
    ///
456
    /// # Panics
457
    ///
458
    /// This function panics if the supplied `repr_align` is not a power of two.
459
    ///
460
    /// # Safety
461
    ///
462
    /// Unsafe code may assume that the contract of this function is satisfied.
463
    #[doc(hidden)]
464
    #[inline]
465
0
    pub const fn new_zst(repr_align: Option<NonZeroUsize>) -> DstLayout {
466
0
        let align = match repr_align {
467
0
            Some(align) => align,
468
0
            None => Self::MIN_ALIGN,
469
        };
470
471
0
        assert!(align.is_power_of_two());
472
473
0
        DstLayout { align, size_info: SizeInfo::Sized { _size: 0 } }
474
0
    }
475
476
    /// Constructs a `DstLayout` which describes `T`.
477
    ///
478
    /// # Safety
479
    ///
480
    /// Unsafe code may assume that `DstLayout` is the correct layout for `T`.
481
    #[doc(hidden)]
482
    #[inline]
483
0
    pub const fn for_type<T>() -> DstLayout {
484
        // SAFETY: `align` is correct by construction. `T: Sized`, and so it is
485
        // sound to initialize `size_info` to `SizeInfo::Sized { size }`; the
486
        // `size` field is also correct by construction.
487
        DstLayout {
488
0
            align: match NonZeroUsize::new(mem::align_of::<T>()) {
489
0
                Some(align) => align,
490
0
                None => unreachable!(),
491
            },
492
0
            size_info: SizeInfo::Sized { _size: mem::size_of::<T>() },
493
        }
494
0
    }
495
496
    /// Constructs a `DstLayout` which describes `[T]`.
497
    ///
498
    /// # Safety
499
    ///
500
    /// Unsafe code may assume that `DstLayout` is the correct layout for `[T]`.
501
0
    const fn for_slice<T>() -> DstLayout {
502
        // SAFETY: The alignment of a slice is equal to the alignment of its
503
        // element type, and so `align` is initialized correctly.
504
        //
505
        // Since this is just a slice type, there is no offset between the
506
        // beginning of the type and the beginning of the slice, so it is
507
        // correct to set `offset: 0`. The `elem_size` is correct by
508
        // construction. Since `[T]` is a (degenerate case of a) slice DST, it
509
        // is correct to initialize `size_info` to `SizeInfo::SliceDst`.
510
        DstLayout {
511
0
            align: match NonZeroUsize::new(mem::align_of::<T>()) {
512
0
                Some(align) => align,
513
0
                None => unreachable!(),
514
            },
515
0
            size_info: SizeInfo::SliceDst(TrailingSliceLayout {
516
0
                _offset: 0,
517
0
                _elem_size: mem::size_of::<T>(),
518
0
            }),
519
        }
520
0
    }
521
522
    /// Like `Layout::extend`, this creates a layout that describes a record
523
    /// whose layout consists of `self` followed by `next` that includes the
524
    /// necessary inter-field padding, but not any trailing padding.
525
    ///
526
    /// In order to match the layout of a `#[repr(C)]` struct, this method
527
    /// should be invoked for each field in declaration order. To add trailing
528
    /// padding, call `DstLayout::pad_to_align` after extending the layout for
529
    /// all fields. If `self` corresponds to a type marked with
530
    /// `repr(packed(N))`, then `repr_packed` should be set to `Some(N)`,
531
    /// otherwise `None`.
532
    ///
533
    /// This method cannot be used to match the layout of a record with the
534
    /// default representation, as that representation is mostly unspecified.
535
    ///
536
    /// # Safety
537
    ///
538
    /// If a (potentially hypothetical) valid `repr(C)` Rust type begins with
539
    /// fields whose layout are `self`, and those fields are immediately
540
    /// followed by a field whose layout is `field`, then unsafe code may rely
541
    /// on `self.extend(field, repr_packed)` producing a layout that correctly
542
    /// encompasses those two components.
543
    ///
544
    /// We make no guarantees to the behavior of this method if these fragments
545
    /// cannot appear in a valid Rust type (e.g., the concatenation of the
546
    /// layouts would lead to a size larger than `isize::MAX`).
547
    #[doc(hidden)]
548
    #[inline]
549
0
    pub const fn extend(self, field: DstLayout, repr_packed: Option<NonZeroUsize>) -> Self {
550
        use util::{core_layout::padding_needed_for, max, min};
551
552
        // If `repr_packed` is `None`, there are no alignment constraints, and
553
        // the value can be defaulted to `THEORETICAL_MAX_ALIGN`.
554
0
        let max_align = match repr_packed {
555
0
            Some(max_align) => max_align,
556
0
            None => Self::THEORETICAL_MAX_ALIGN,
557
        };
558
559
0
        assert!(max_align.is_power_of_two());
560
561
        // We use Kani to prove that this method is robust to future increases
562
        // in Rust's maximum allowed alignment. However, if such a change ever
563
        // actually occurs, we'd like to be notified via assertion failures.
564
        #[cfg(not(kani))]
565
        {
566
0
            debug_assert!(self.align.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
567
0
            debug_assert!(field.align.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
568
0
            if let Some(repr_packed) = repr_packed {
569
0
                debug_assert!(repr_packed.get() <= DstLayout::CURRENT_MAX_ALIGN.get());
570
0
            }
571
        }
572
573
        // The field's alignment is clamped by `repr_packed` (i.e., the
574
        // `repr(packed(N))` attribute, if any) [1].
575
        //
576
        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
577
        //
578
        //   The alignments of each field, for the purpose of positioning
579
        //   fields, is the smaller of the specified alignment and the alignment
580
        //   of the field's type.
581
0
        let field_align = min(field.align, max_align);
582
583
        // The struct's alignment is the maximum of its previous alignment and
584
        // `field_align`.
585
0
        let align = max(self.align, field_align);
586
587
0
        let size_info = match self.size_info {
588
            // If the layout is already a DST, we panic; DSTs cannot be extended
589
            // with additional fields.
590
0
            SizeInfo::SliceDst(..) => panic!("Cannot extend a DST with additional fields."),
591
592
0
            SizeInfo::Sized { _size: preceding_size } => {
593
                // Compute the minimum amount of inter-field padding needed to
594
                // satisfy the field's alignment, and offset of the trailing
595
                // field. [1]
596
                //
597
                // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
598
                //
599
                //   Inter-field padding is guaranteed to be the minimum
600
                //   required in order to satisfy each field's (possibly
601
                //   altered) alignment.
602
0
                let padding = padding_needed_for(preceding_size, field_align);
603
604
                // This will not panic (and is proven to not panic, with Kani)
605
                // if the layout components can correspond to a leading layout
606
                // fragment of a valid Rust type, but may panic otherwise (e.g.,
607
                // combining or aligning the components would create a size
608
                // exceeding `isize::MAX`).
609
0
                let offset = match preceding_size.checked_add(padding) {
610
0
                    Some(offset) => offset,
611
0
                    None => panic!("Adding padding to `self`'s size overflows `usize`."),
612
                };
613
614
0
                match field.size_info {
615
0
                    SizeInfo::Sized { _size: field_size } => {
616
                        // If the trailing field is sized, the resulting layout
617
                        // will be sized. Its size will be the sum of the
618
                        // preceeding layout, the size of the new field, and the
619
                        // size of inter-field padding between the two.
620
                        //
621
                        // This will not panic (and is proven with Kani to not
622
                        // panic) if the layout components can correspond to a
623
                        // leading layout fragment of a valid Rust type, but may
624
                        // panic otherwise (e.g., combining or aligning the
625
                        // components would create a size exceeding
626
                        // `usize::MAX`).
627
0
                        let size = match offset.checked_add(field_size) {
628
0
                            Some(size) => size,
629
0
                            None => panic!("`field` cannot be appended without the total size overflowing `usize`"),
630
                        };
631
0
                        SizeInfo::Sized { _size: size }
632
                    }
633
                    SizeInfo::SliceDst(TrailingSliceLayout {
634
0
                        _offset: trailing_offset,
635
0
                        _elem_size,
636
                    }) => {
637
                        // If the trailing field is dynamically sized, so too
638
                        // will the resulting layout. The offset of the trailing
639
                        // slice component is the sum of the offset of the
640
                        // trailing field and the trailing slice offset within
641
                        // that field.
642
                        //
643
                        // This will not panic (and is proven with Kani to not
644
                        // panic) if the layout components can correspond to a
645
                        // leading layout fragment of a valid Rust type, but may
646
                        // panic otherwise (e.g., combining or aligning the
647
                        // components would create a size exceeding
648
                        // `usize::MAX`).
649
0
                        let offset = match offset.checked_add(trailing_offset) {
650
0
                            Some(offset) => offset,
651
0
                            None => panic!("`field` cannot be appended without the total size overflowing `usize`"),
652
                        };
653
0
                        SizeInfo::SliceDst(TrailingSliceLayout { _offset: offset, _elem_size })
654
                    }
655
                }
656
            }
657
        };
658
659
0
        DstLayout { align, size_info }
660
0
    }
661
662
    /// Like `Layout::pad_to_align`, this routine rounds the size of this layout
663
    /// up to the nearest multiple of this type's alignment or `repr_packed`
664
    /// (whichever is less). This method leaves DST layouts unchanged, since the
665
    /// trailing padding of DSTs is computed at runtime.
666
    ///
667
    /// In order to match the layout of a `#[repr(C)]` struct, this method
668
    /// should be invoked after the invocations of [`DstLayout::extend`]. If
669
    /// `self` corresponds to a type marked with `repr(packed(N))`, then
670
    /// `repr_packed` should be set to `Some(N)`, otherwise `None`.
671
    ///
672
    /// This method cannot be used to match the layout of a record with the
673
    /// default representation, as that representation is mostly unspecified.
674
    ///
675
    /// # Safety
676
    ///
677
    /// If a (potentially hypothetical) valid `repr(C)` type begins with fields
678
    /// whose layout are `self` followed only by zero or more bytes of trailing
679
    /// padding (not included in `self`), then unsafe code may rely on
680
    /// `self.pad_to_align(repr_packed)` producing a layout that correctly
681
    /// encapsulates the layout of that type.
682
    ///
683
    /// We make no guarantees to the behavior of this method if `self` cannot
684
    /// appear in a valid Rust type (e.g., because the addition of trailing
685
    /// padding would lead to a size larger than `isize::MAX`).
686
    #[doc(hidden)]
687
    #[inline]
688
0
    pub const fn pad_to_align(self) -> Self {
689
        use util::core_layout::padding_needed_for;
690
691
0
        let size_info = match self.size_info {
692
            // For sized layouts, we add the minimum amount of trailing padding
693
            // needed to satisfy alignment.
694
0
            SizeInfo::Sized { _size: unpadded_size } => {
695
0
                let padding = padding_needed_for(unpadded_size, self.align);
696
0
                let size = match unpadded_size.checked_add(padding) {
697
0
                    Some(size) => size,
698
0
                    None => panic!("Adding padding caused size to overflow `usize`."),
699
                };
700
0
                SizeInfo::Sized { _size: size }
701
            }
702
            // For DST layouts, trailing padding depends on the length of the
703
            // trailing DST and is computed at runtime. This does not alter the
704
            // offset or element size of the layout, so we leave `size_info`
705
            // unchanged.
706
0
            size_info @ SizeInfo::SliceDst(_) => size_info,
707
        };
708
709
0
        DstLayout { align: self.align, size_info }
710
0
    }
711
712
    /// Validates that a cast is sound from a layout perspective.
713
    ///
714
    /// Validates that the size and alignment requirements of a type with the
715
    /// layout described in `self` would not be violated by performing a
716
    /// `cast_type` cast from a pointer with address `addr` which refers to a
717
    /// memory region of size `bytes_len`.
718
    ///
719
    /// If the cast is valid, `validate_cast_and_convert_metadata` returns
720
    /// `(elems, split_at)`. If `self` describes a dynamically-sized type, then
721
    /// `elems` is the maximum number of trailing slice elements for which a
722
    /// cast would be valid (for sized types, `elem` is meaningless and should
723
    /// be ignored). `split_at` is the index at which to split the memory region
724
    /// in order for the prefix (suffix) to contain the result of the cast, and
725
    /// in order for the remaining suffix (prefix) to contain the leftover
726
    /// bytes.
727
    ///
728
    /// There are three conditions under which a cast can fail:
729
    /// - The smallest possible value for the type is larger than the provided
730
    ///   memory region
731
    /// - A prefix cast is requested, and `addr` does not satisfy `self`'s
732
    ///   alignment requirement
733
    /// - A suffix cast is requested, and `addr + bytes_len` does not satisfy
734
    ///   `self`'s alignment requirement (as a consequence, since all instances
735
    ///   of the type are a multiple of its alignment, no size for the type will
736
    ///   result in a starting address which is properly aligned)
737
    ///
738
    /// # Safety
739
    ///
740
    /// The caller may assume that this implementation is correct, and may rely
741
    /// on that assumption for the soundness of their code. In particular, the
742
    /// caller may assume that, if `validate_cast_and_convert_metadata` returns
743
    /// `Some((elems, split_at))`, then:
744
    /// - A pointer to the type (for dynamically sized types, this includes
745
    ///   `elems` as its pointer metadata) describes an object of size `size <=
746
    ///   bytes_len`
747
    /// - If this is a prefix cast:
748
    ///   - `addr` satisfies `self`'s alignment
749
    ///   - `size == split_at`
750
    /// - If this is a suffix cast:
751
    ///   - `split_at == bytes_len - size`
752
    ///   - `addr + split_at` satisfies `self`'s alignment
753
    ///
754
    /// Note that this method does *not* ensure that a pointer constructed from
755
    /// its return values will be a valid pointer. In particular, this method
756
    /// does not reason about `isize` overflow, which is a requirement of many
757
    /// Rust pointer APIs, and may at some point be determined to be a validity
758
    /// invariant of pointer types themselves. This should never be a problem so
759
    /// long as the arguments to this method are derived from a known-valid
760
    /// pointer (e.g., one derived from a safe Rust reference), but it is
761
    /// nonetheless the caller's responsibility to justify that pointer
762
    /// arithmetic will not overflow based on a safety argument *other than* the
763
    /// mere fact that this method returned successfully.
764
    ///
765
    /// # Panics
766
    ///
767
    /// `validate_cast_and_convert_metadata` will panic if `self` describes a
768
    /// DST whose trailing slice element is zero-sized.
769
    ///
770
    /// If `addr + bytes_len` overflows `usize`,
771
    /// `validate_cast_and_convert_metadata` may panic, or it may return
772
    /// incorrect results. No guarantees are made about when
773
    /// `validate_cast_and_convert_metadata` will panic. The caller should not
774
    /// rely on `validate_cast_and_convert_metadata` panicking in any particular
775
    /// condition, even if `debug_assertions` are enabled.
776
    #[allow(unused)]
777
0
    const fn validate_cast_and_convert_metadata(
778
0
        &self,
779
0
        addr: usize,
780
0
        bytes_len: usize,
781
0
        cast_type: _CastType,
782
0
    ) -> Option<(usize, usize)> {
783
        // `debug_assert!`, but with `#[allow(clippy::arithmetic_side_effects)]`.
784
        macro_rules! __debug_assert {
785
            ($e:expr $(, $msg:expr)?) => {
786
                debug_assert!({
787
                    #[allow(clippy::arithmetic_side_effects)]
788
                    let e = $e;
789
                    e
790
                } $(, $msg)?);
791
            };
792
        }
793
794
        // Note that, in practice, `self` is always a compile-time constant. We
795
        // do this check earlier than needed to ensure that we always panic as a
796
        // result of bugs in the program (such as calling this function on an
797
        // invalid type) instead of allowing this panic to be hidden if the cast
798
        // would have failed anyway for runtime reasons (such as a too-small
799
        // memory region).
800
        //
801
        // TODO(#67): Once our MSRV is 1.65, use let-else:
802
        // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements
803
0
        let size_info = match self.size_info.try_to_nonzero_elem_size() {
804
0
            Some(size_info) => size_info,
805
0
            None => panic!("attempted to cast to slice type with zero-sized element"),
806
        };
807
808
        // Precondition
809
0
        __debug_assert!(addr.checked_add(bytes_len).is_some(), "`addr` + `bytes_len` > usize::MAX");
810
811
        // Alignment checks go in their own block to avoid introducing variables
812
        // into the top-level scope.
813
        {
814
            // We check alignment for `addr` (for prefix casts) or `addr +
815
            // bytes_len` (for suffix casts). For a prefix cast, the correctness
816
            // of this check is trivial - `addr` is the address the object will
817
            // live at.
818
            //
819
            // For a suffix cast, we know that all valid sizes for the type are
820
            // a multiple of the alignment (and by safety precondition, we know
821
            // `DstLayout` may only describe valid Rust types). Thus, a
822
            // validly-sized instance which lives at a validly-aligned address
823
            // must also end at a validly-aligned address. Thus, if the end
824
            // address for a suffix cast (`addr + bytes_len`) is not aligned,
825
            // then no valid start address will be aligned either.
826
0
            let offset = match cast_type {
827
0
                _CastType::_Prefix => 0,
828
0
                _CastType::_Suffix => bytes_len,
829
            };
830
831
            // Addition is guaranteed not to overflow because `offset <=
832
            // bytes_len`, and `addr + bytes_len <= usize::MAX` is a
833
            // precondition of this method. Modulus is guaranteed not to divide
834
            // by 0 because `align` is non-zero.
835
            #[allow(clippy::arithmetic_side_effects)]
836
0
            if (addr + offset) % self.align.get() != 0 {
837
0
                return None;
838
0
            }
839
        }
840
841
0
        let (elems, self_bytes) = match size_info {
842
0
            SizeInfo::Sized { _size: size } => {
843
0
                if size > bytes_len {
844
0
                    return None;
845
0
                }
846
0
                (0, size)
847
            }
848
0
            SizeInfo::SliceDst(TrailingSliceLayout { _offset: offset, _elem_size: elem_size }) => {
849
                // Calculate the maximum number of bytes that could be consumed
850
                // - any number of bytes larger than this will either not be a
851
                // multiple of the alignment, or will be larger than
852
                // `bytes_len`.
853
0
                let max_total_bytes =
854
0
                    util::round_down_to_next_multiple_of_alignment(bytes_len, self.align);
855
                // Calculate the maximum number of bytes that could be consumed
856
                // by the trailing slice.
857
                //
858
                // TODO(#67): Once our MSRV is 1.65, use let-else:
859
                // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements
860
0
                let max_slice_and_padding_bytes = match max_total_bytes.checked_sub(offset) {
861
0
                    Some(max) => max,
862
                    // `bytes_len` too small even for 0 trailing slice elements.
863
0
                    None => return None,
864
                };
865
866
                // Calculate the number of elements that fit in
867
                // `max_slice_and_padding_bytes`; any remaining bytes will be
868
                // considered padding.
869
                //
870
                // Guaranteed not to divide by zero: `elem_size` is non-zero.
871
                #[allow(clippy::arithmetic_side_effects)]
872
0
                let elems = max_slice_and_padding_bytes / elem_size.get();
873
                // Guaranteed not to overflow on multiplication: `usize::MAX >=
874
                // max_slice_and_padding_bytes >= (max_slice_and_padding_bytes /
875
                // elem_size) * elem_size`.
876
                //
877
                // Guaranteed not to overflow on addition:
878
                // - max_slice_and_padding_bytes == max_total_bytes - offset
879
                // - elems * elem_size <= max_slice_and_padding_bytes == max_total_bytes - offset
880
                // - elems * elem_size + offset <= max_total_bytes <= usize::MAX
881
                #[allow(clippy::arithmetic_side_effects)]
882
0
                let without_padding = offset + elems * elem_size.get();
883
                // `self_bytes` is equal to the offset bytes plus the bytes
884
                // consumed by the trailing slice plus any padding bytes
885
                // required to satisfy the alignment. Note that we have computed
886
                // the maximum number of trailing slice elements that could fit
887
                // in `self_bytes`, so any padding is guaranteed to be less than
888
                // the size of an extra element.
889
                //
890
                // Guaranteed not to overflow:
891
                // - By previous comment: without_padding == elems * elem_size +
892
                //   offset <= max_total_bytes
893
                // - By construction, `max_total_bytes` is a multiple of
894
                //   `self.align`.
895
                // - At most, adding padding needed to round `without_padding`
896
                //   up to the next multiple of the alignment will bring
897
                //   `self_bytes` up to `max_total_bytes`.
898
                #[allow(clippy::arithmetic_side_effects)]
899
0
                let self_bytes = without_padding
900
0
                    + util::core_layout::padding_needed_for(without_padding, self.align);
901
0
                (elems, self_bytes)
902
            }
903
        };
904
905
0
        __debug_assert!(self_bytes <= bytes_len);
906
907
0
        let split_at = match cast_type {
908
0
            _CastType::_Prefix => self_bytes,
909
            // Guaranteed not to underflow:
910
            // - In the `Sized` branch, only returns `size` if `size <=
911
            //   bytes_len`.
912
            // - In the `SliceDst` branch, calculates `self_bytes <=
913
            //   max_toatl_bytes`, which is upper-bounded by `bytes_len`.
914
            #[allow(clippy::arithmetic_side_effects)]
915
0
            _CastType::_Suffix => bytes_len - self_bytes,
916
        };
917
918
0
        Some((elems, split_at))
919
0
    }
920
}
921
922
/// A trait which carries information about a type's layout that is used by the
923
/// internals of this crate.
924
///
925
/// This trait is not meant for consumption by code outside of this crate. While
926
/// the normal semver stability guarantees apply with respect to which types
927
/// implement this trait and which trait implementations are implied by this
928
/// trait, no semver stability guarantees are made regarding its internals; they
929
/// may change at any time, and code which makes use of them may break.
930
///
931
/// # Safety
932
///
933
/// This trait does not convey any safety guarantees to code outside this crate.
934
#[doc(hidden)] // TODO: Remove this once KnownLayout is used by other APIs
935
pub unsafe trait KnownLayout {
936
    // The `Self: Sized` bound makes it so that `KnownLayout` can still be
937
    // object safe. It's not currently object safe thanks to `const LAYOUT`, and
938
    // it likely won't be in the future, but there's no reason not to be
939
    // forwards-compatible with object safety.
940
    #[doc(hidden)]
941
    fn only_derive_is_allowed_to_implement_this_trait()
942
    where
943
        Self: Sized;
944
945
    #[doc(hidden)]
946
    const LAYOUT: DstLayout;
947
948
    /// SAFETY: The returned pointer has the same address and provenance as
949
    /// `bytes`. If `Self` is a DST, the returned pointer's referent has `elems`
950
    /// elements in its trailing slice. If `Self` is sized, `elems` is ignored.
951
    #[doc(hidden)]
952
    fn raw_from_ptr_len(bytes: NonNull<u8>, elems: usize) -> NonNull<Self>;
953
}
954
955
// SAFETY: Delegates safety to `DstLayout::for_slice`.
956
unsafe impl<T: KnownLayout> KnownLayout for [T] {
957
    #[allow(clippy::missing_inline_in_public_items)]
958
0
    fn only_derive_is_allowed_to_implement_this_trait()
959
0
    where
960
0
        Self: Sized,
961
    {
962
0
    }
963
    const LAYOUT: DstLayout = DstLayout::for_slice::<T>();
964
965
    // SAFETY: `.cast` preserves address and provenance. The returned pointer
966
    // refers to an object with `elems` elements by construction.
967
    #[inline(always)]
968
0
    fn raw_from_ptr_len(data: NonNull<u8>, elems: usize) -> NonNull<Self> {
969
        // TODO(#67): Remove this allow. See NonNullExt for more details.
970
        #[allow(unstable_name_collisions)]
971
0
        NonNull::slice_from_raw_parts(data.cast::<T>(), elems)
972
0
    }
973
}
974
975
#[rustfmt::skip]
976
impl_known_layout!(
977
    (),
978
    u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, f32, f64,
979
    bool, char,
980
    NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32,
981
    NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize
982
);
983
#[rustfmt::skip]
984
impl_known_layout!(
985
    T         => Option<T>,
986
    T: ?Sized => PhantomData<T>,
987
    T         => Wrapping<T>,
988
    T         => MaybeUninit<T>,
989
    T: ?Sized => *const T,
990
    T: ?Sized => *mut T,
991
);
992
impl_known_layout!(const N: usize, T => [T; N]);
993
994
safety_comment! {
995
    /// SAFETY:
996
    /// `str` and `ManuallyDrop<[T]>` [1] have the same representations as
997
    /// `[u8]` and `[T]` repsectively. `str` has different bit validity than
998
    /// `[u8]`, but that doesn't affect the soundness of this impl.
999
    ///
1000
    /// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
1001
    ///
1002
    ///   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
1003
    ///   validity as `T`
1004
    ///
1005
    /// TODO(#429):
1006
    /// -  Add quotes from docs.
1007
    /// -  Once [1] (added in
1008
    /// https://github.com/rust-lang/rust/pull/115522) is available on stable,
1009
    /// quote the stable docs instead of the nightly docs.
1010
    unsafe_impl_known_layout!(#[repr([u8])] str);
1011
    unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] ManuallyDrop<T>);
1012
}
1013
1014
/// Analyzes whether a type is [`FromZeroes`].
1015
///
1016
/// This derive analyzes, at compile time, whether the annotated type satisfies
1017
/// the [safety conditions] of `FromZeroes` and implements `FromZeroes` if it is
1018
/// sound to do so. This derive can be applied to structs, enums, and unions;
1019
/// e.g.:
1020
///
1021
/// ```
1022
/// # use zerocopy_derive::FromZeroes;
1023
/// #[derive(FromZeroes)]
1024
/// struct MyStruct {
1025
/// # /*
1026
///     ...
1027
/// # */
1028
/// }
1029
///
1030
/// #[derive(FromZeroes)]
1031
/// #[repr(u8)]
1032
/// enum MyEnum {
1033
/// #   Variant0,
1034
/// # /*
1035
///     ...
1036
/// # */
1037
/// }
1038
///
1039
/// #[derive(FromZeroes)]
1040
/// union MyUnion {
1041
/// #   variant: u8,
1042
/// # /*
1043
///     ...
1044
/// # */
1045
/// }
1046
/// ```
1047
///
1048
/// [safety conditions]: trait@FromZeroes#safety
1049
///
1050
/// # Analysis
1051
///
1052
/// *This section describes, roughly, the analysis performed by this derive to
1053
/// determine whether it is sound to implement `FromZeroes` for a given type.
1054
/// Unless you are modifying the implementation of this derive, or attempting to
1055
/// manually implement `FromZeroes` for a type yourself, you don't need to read
1056
/// this section.*
1057
///
1058
/// If a type has the following properties, then this derive can implement
1059
/// `FromZeroes` for that type:
1060
///
1061
/// - If the type is a struct, all of its fields must be `FromZeroes`.
1062
/// - If the type is an enum, it must be C-like (meaning that all variants have
1063
///   no fields) and it must have a variant with a discriminant of `0`. See [the
1064
///   reference] for a description of how discriminant values are chosen.
1065
/// - The type must not contain any [`UnsafeCell`]s (this is required in order
1066
///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
1067
///   memory). The type may contain references or pointers to `UnsafeCell`s so
1068
///   long as those values can themselves be initialized from zeroes
1069
///   (`FromZeroes` is not currently implemented for, e.g.,
1070
///   `Option<&UnsafeCell<_>>`, but it could be one day).
1071
///
1072
/// This analysis is subject to change. Unsafe code may *only* rely on the
1073
/// documented [safety conditions] of `FromZeroes`, and must *not* rely on the
1074
/// implementation details of this derive.
1075
///
1076
/// [the reference]: https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
1077
/// [`UnsafeCell`]: core::cell::UnsafeCell
1078
///
1079
/// ## Why isn't an explicit representation required for structs?
1080
///
1081
/// Neither this derive, nor the [safety conditions] of `FromZeroes`, requires
1082
/// that structs are marked with `#[repr(C)]`.
1083
///
1084
/// Per the [Rust reference](reference),
1085
///
1086
/// > The representation of a type can change the padding between fields, but
1087
/// does not change the layout of the fields themselves.
1088
///
1089
/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
1090
///
1091
/// Since the layout of structs only consists of padding bytes and field bytes,
1092
/// a struct is soundly `FromZeroes` if:
1093
/// 1. its padding is soundly `FromZeroes`, and
1094
/// 2. its fields are soundly `FromZeroes`.
1095
///
1096
/// The answer to the first question is always yes: padding bytes do not have
1097
/// any validity constraints. A [discussion] of this question in the Unsafe Code
1098
/// Guidelines Working Group concluded that it would be virtually unimaginable
1099
/// for future versions of rustc to add validity constraints to padding bytes.
1100
///
1101
/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
1102
///
1103
/// Whether a struct is soundly `FromZeroes` therefore solely depends on whether
1104
/// its fields are `FromZeroes`.
1105
// TODO(#146): Document why we don't require an enum to have an explicit `repr`
1106
// attribute.
1107
#[cfg(any(feature = "derive", test))]
1108
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1109
pub use zerocopy_derive::FromZeroes;
1110
1111
/// Types whose validity can be checked at runtime, allowing them to be
1112
/// conditionally converted from byte slices.
1113
///
1114
/// WARNING: Do not implement this trait yourself! Instead, use
1115
/// `#[derive(TryFromBytes)]`.
1116
///
1117
/// `TryFromBytes` types can safely be deserialized from an untrusted sequence
1118
/// of bytes by performing a runtime check that the byte sequence contains a
1119
/// valid instance of `Self`.
1120
///
1121
/// `TryFromBytes` is ignorant of byte order. For byte order-aware types, see
1122
/// the [`byteorder`] module.
1123
///
1124
/// # What is a "valid instance"?
1125
///
1126
/// In Rust, each type has *bit validity*, which refers to the set of bit
1127
/// patterns which may appear in an instance of that type. It is impossible for
1128
/// safe Rust code to produce values which violate bit validity (ie, values
1129
/// outside of the "valid" set of bit patterns). If `unsafe` code produces an
1130
/// invalid value, this is considered [undefined behavior].
1131
///
1132
/// Rust's bit validity rules are currently being decided, which means that some
1133
/// types have three classes of bit patterns: those which are definitely valid,
1134
/// and whose validity is documented in the language; those which may or may not
1135
/// be considered valid at some point in the future; and those which are
1136
/// definitely invalid.
1137
///
1138
/// Zerocopy takes a conservative approach, and only considers a bit pattern to
1139
/// be valid if its validity is a documenteed guarantee provided by the
1140
/// language.
1141
///
1142
/// For most use cases, Rust's current guarantees align with programmers'
1143
/// intuitions about what ought to be valid. As a result, zerocopy's
1144
/// conservatism should not affect most users. One notable exception is unions,
1145
/// whose bit validity is very up in the air; zerocopy does not permit
1146
/// implementing `TryFromBytes` for any union type.
1147
///
1148
/// If you are negatively affected by lack of support for a particular type,
1149
/// we encourage you to let us know by [filing an issue][github-repo].
1150
///
1151
/// # Safety
1152
///
1153
/// On its own, `T: TryFromBytes` does not make any guarantees about the layout
1154
/// or representation of `T`. It merely provides the ability to perform a
1155
/// validity check at runtime via methods like [`try_from_ref`].
1156
///
1157
/// Currently, it is not possible to stably implement `TryFromBytes` other than
1158
/// by using `#[derive(TryFromBytes)]`. While there are `#[doc(hidden)]` items
1159
/// on this trait that provide well-defined safety invariants, no stability
1160
/// guarantees are made with respect to these items. In particular, future
1161
/// releases of zerocopy may make backwards-breaking changes to these items,
1162
/// including changes that only affect soundness, which may cause code which
1163
/// uses those items to silently become unsound.
1164
///
1165
/// [undefined behavior]: https://raphlinus.github.io/programming/rust/2018/08/17/undefined-behavior.html
1166
/// [github-repo]: https://github.com/google/zerocopy
1167
/// [`try_from_ref`]: TryFromBytes::try_from_ref
1168
// TODO(#5): Update `try_from_ref` doc link once it exists
1169
#[doc(hidden)]
1170
pub unsafe trait TryFromBytes {
1171
    /// Does a given memory range contain a valid instance of `Self`?
1172
    ///
1173
    /// # Safety
1174
    ///
1175
    /// ## Preconditions
1176
    ///
1177
    /// The memory referenced by `candidate` may only be accessed via reads for
1178
    /// the duration of this method call. This prohibits writes through mutable
1179
    /// references and through [`UnsafeCell`]s. There may exist immutable
1180
    /// references to the same memory which contain `UnsafeCell`s so long as:
1181
    /// - Those `UnsafeCell`s exist at the same byte ranges as `UnsafeCell`s in
1182
    ///   `Self`. This is a bidirectional property: `Self` may not contain
1183
    ///   `UnsafeCell`s where other references to the same memory do not, and
1184
    ///   vice-versa.
1185
    /// - Those `UnsafeCell`s are never used to perform mutation for the
1186
    ///   duration of this method call.
1187
    ///
1188
    /// The memory referenced by `candidate` may not be referenced by any
1189
    /// mutable references even if these references are not used to perform
1190
    /// mutation.
1191
    ///
1192
    /// `candidate` is not required to refer to a valid `Self`. However, it must
1193
    /// satisfy the requirement that uninitialized bytes may only be present
1194
    /// where it is possible for them to be present in `Self`. This is a dynamic
1195
    /// property: if, at a particular byte offset, a valid enum discriminant is
1196
    /// set, the subsequent bytes may only have uninitialized bytes as
1197
    /// specificed by the corresponding enum.
1198
    ///
1199
    /// Formally, given `len = size_of_val_raw(candidate)`, at every byte
1200
    /// offset, `b`, in the range `[0, len)`:
1201
    /// - If, in all instances `s: Self` of length `len`, the byte at offset `b`
1202
    ///   in `s` is initialized, then the byte at offset `b` within `*candidate`
1203
    ///   must be initialized.
1204
    /// - Let `c` be the contents of the byte range `[0, b)` in `*candidate`.
1205
    ///   Let `S` be the subset of valid instances of `Self` of length `len`
1206
    ///   which contain `c` in the offset range `[0, b)`. If, for all instances
1207
    ///   of `s: Self` in `S`, the byte at offset `b` in `s` is initialized,
1208
    ///   then the byte at offset `b` in `*candidate` must be initialized.
1209
    ///
1210
    ///   Pragmatically, this means that if `*candidate` is guaranteed to
1211
    ///   contain an enum type at a particular offset, and the enum discriminant
1212
    ///   stored in `*candidate` corresponds to a valid variant of that enum
1213
    ///   type, then it is guaranteed that the appropriate bytes of `*candidate`
1214
    ///   are initialized as defined by that variant's bit validity (although
1215
    ///   note that the variant may contain another enum type, in which case the
1216
    ///   same rules apply depending on the state of its discriminant, and so on
1217
    ///   recursively).
1218
    ///
1219
    /// ## Postconditions
1220
    ///
1221
    /// Unsafe code may assume that, if `is_bit_valid(candidate)` returns true,
1222
    /// `*candidate` contains a valid `Self`.
1223
    ///
1224
    /// # Panics
1225
    ///
1226
    /// `is_bit_valid` may panic. Callers are responsible for ensuring that any
1227
    /// `unsafe` code remains sound even in the face of `is_bit_valid`
1228
    /// panicking. (We support user-defined validation routines; so long as
1229
    /// these routines are not required to be `unsafe`, there is no way to
1230
    /// ensure that these do not generate panics.)
1231
    ///
1232
    /// [`UnsafeCell`]: core::cell::UnsafeCell
1233
    #[doc(hidden)]
1234
    unsafe fn is_bit_valid(candidate: Ptr<'_, Self>) -> bool;
1235
1236
    /// Attempts to interpret a byte slice as a `Self`.
1237
    ///
1238
    /// `try_from_ref` validates that `bytes` contains a valid `Self`, and that
1239
    /// it satisfies `Self`'s alignment requirement. If it does, then `bytes` is
1240
    /// reinterpreted as a `Self`.
1241
    ///
1242
    /// Note that Rust's bit validity rules are still being decided. As such,
1243
    /// there exist types whose bit validity is ambiguous. See the
1244
    /// `TryFromBytes` docs for a discussion of how these cases are handled.
1245
    // TODO(#251): In a future in which we distinguish between `FromBytes` and
1246
    // `RefFromBytes`, this requires `where Self: RefFromBytes` to disallow
1247
    // interior mutability.
1248
    #[inline]
1249
    #[doc(hidden)] // TODO(#5): Finalize name before remove this attribute.
1250
0
    fn try_from_ref(bytes: &[u8]) -> Option<&Self>
1251
0
    where
1252
0
        Self: KnownLayout,
1253
    {
1254
0
        let maybe_self = Ptr::from(bytes).try_cast_into_no_leftover::<Self>()?;
1255
1256
        // SAFETY:
1257
        // - Since `bytes` is an immutable reference, we know that no mutable
1258
        //   references exist to this memory region.
1259
        // - Since `[u8]` contains no `UnsafeCell`s, we know there are no
1260
        //   `&UnsafeCell` references to this memory region.
1261
        // - Since we don't permit implementing `TryFromBytes` for types which
1262
        //   contain `UnsafeCell`s, there are no `UnsafeCell`s in `Self`, and so
1263
        //   the requirement that all references contain `UnsafeCell`s at the
1264
        //   same offsets is trivially satisfied.
1265
        // - All bytes of `bytes` are initialized.
1266
        //
1267
        // This call may panic. If that happens, it doesn't cause any soundness
1268
        // issues, as we have not generated any invalid state which we need to
1269
        // fix before returning.
1270
0
        if unsafe { !Self::is_bit_valid(maybe_self) } {
1271
0
            return None;
1272
0
        }
1273
1274
        // SAFETY:
1275
        // - Preconditions for `as_ref`:
1276
        //   - `is_bit_valid` guarantees that `*maybe_self` contains a valid
1277
        //     `Self`. Since `&[u8]` does not permit interior mutation, this
1278
        //     cannot be invalidated after this method returns.
1279
        //   - Since the argument and return types are immutable references,
1280
        //     Rust will prevent the caller from producing any mutable
1281
        //     references to the same memory region.
1282
        //   - Since `Self` is not allowed to contain any `UnsafeCell`s and the
1283
        //     same is true of `[u8]`, interior mutation is not possible. Thus,
1284
        //     no mutation is possible. For the same reason, there is no
1285
        //     mismatch between the two types in terms of which byte ranges are
1286
        //     referenced as `UnsafeCell`s.
1287
        // - Since interior mutation isn't possible within `Self`, there's no
1288
        //   way for the returned reference to be used to modify the byte range,
1289
        //   and thus there's no way for the returned reference to be used to
1290
        //   write an invalid `[u8]` which would be observable via the original
1291
        //   `&[u8]`.
1292
0
        Some(unsafe { maybe_self.as_ref() })
1293
0
    }
1294
}
1295
1296
/// Types for which a sequence of bytes all set to zero represents a valid
1297
/// instance of the type.
1298
///
1299
/// Any memory region of the appropriate length which is guaranteed to contain
1300
/// only zero bytes can be viewed as any `FromZeroes` type with no runtime
1301
/// overhead. This is useful whenever memory is known to be in a zeroed state,
1302
/// such memory returned from some allocation routines.
1303
///
1304
/// # Implementation
1305
///
1306
/// **Do not implement this trait yourself!** Instead, use
1307
/// [`#[derive(FromZeroes)]`][derive] (requires the `derive` Cargo feature);
1308
/// e.g.:
1309
///
1310
/// ```
1311
/// # use zerocopy_derive::FromZeroes;
1312
/// #[derive(FromZeroes)]
1313
/// struct MyStruct {
1314
/// # /*
1315
///     ...
1316
/// # */
1317
/// }
1318
///
1319
/// #[derive(FromZeroes)]
1320
/// #[repr(u8)]
1321
/// enum MyEnum {
1322
/// #   Variant0,
1323
/// # /*
1324
///     ...
1325
/// # */
1326
/// }
1327
///
1328
/// #[derive(FromZeroes)]
1329
/// union MyUnion {
1330
/// #   variant: u8,
1331
/// # /*
1332
///     ...
1333
/// # */
1334
/// }
1335
/// ```
1336
///
1337
/// This derive performs a sophisticated, compile-time safety analysis to
1338
/// determine whether a type is `FromZeroes`.
1339
///
1340
/// # Safety
1341
///
1342
/// *This section describes what is required in order for `T: FromZeroes`, and
1343
/// what unsafe code may assume of such types. If you don't plan on implementing
1344
/// `FromZeroes` manually, and you don't plan on writing unsafe code that
1345
/// operates on `FromZeroes` types, then you don't need to read this section.*
1346
///
1347
/// If `T: FromZeroes`, then unsafe code may assume that:
1348
/// - It is sound to treat any initialized sequence of zero bytes of length
1349
///   `size_of::<T>()` as a `T`.
1350
/// - Given `b: &[u8]` where `b.len() == size_of::<T>()`, `b` is aligned to
1351
///   `align_of::<T>()`, and `b` contains only zero bytes, it is sound to
1352
///   construct a `t: &T` at the same address as `b`, and it is sound for both
1353
///   `b` and `t` to be live at the same time.
1354
///
1355
/// If a type is marked as `FromZeroes` which violates this contract, it may
1356
/// cause undefined behavior.
1357
///
1358
/// `#[derive(FromZeroes)]` only permits [types which satisfy these
1359
/// requirements][derive-analysis].
1360
///
1361
#[cfg_attr(
1362
    feature = "derive",
1363
    doc = "[derive]: zerocopy_derive::FromZeroes",
1364
    doc = "[derive-analysis]: zerocopy_derive::FromZeroes#analysis"
1365
)]
1366
#[cfg_attr(
1367
    not(feature = "derive"),
1368
    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeroes.html"),
1369
    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromZeroes.html#analysis"),
1370
)]
1371
pub unsafe trait FromZeroes {
1372
    // The `Self: Sized` bound makes it so that `FromZeroes` is still object
1373
    // safe.
1374
    #[doc(hidden)]
1375
    fn only_derive_is_allowed_to_implement_this_trait()
1376
    where
1377
        Self: Sized;
1378
1379
    /// Overwrites `self` with zeroes.
1380
    ///
1381
    /// Sets every byte in `self` to 0. While this is similar to doing `*self =
1382
    /// Self::new_zeroed()`, it differs in that `zero` does not semantically
1383
    /// drop the current value and replace it with a new one - it simply
1384
    /// modifies the bytes of the existing value.
1385
    ///
1386
    /// # Examples
1387
    ///
1388
    /// ```
1389
    /// # use zerocopy::FromZeroes;
1390
    /// # use zerocopy_derive::*;
1391
    /// #
1392
    /// #[derive(FromZeroes)]
1393
    /// #[repr(C)]
1394
    /// struct PacketHeader {
1395
    ///     src_port: [u8; 2],
1396
    ///     dst_port: [u8; 2],
1397
    ///     length: [u8; 2],
1398
    ///     checksum: [u8; 2],
1399
    /// }
1400
    ///
1401
    /// let mut header = PacketHeader {
1402
    ///     src_port: 100u16.to_be_bytes(),
1403
    ///     dst_port: 200u16.to_be_bytes(),
1404
    ///     length: 300u16.to_be_bytes(),
1405
    ///     checksum: 400u16.to_be_bytes(),
1406
    /// };
1407
    ///
1408
    /// header.zero();
1409
    ///
1410
    /// assert_eq!(header.src_port, [0, 0]);
1411
    /// assert_eq!(header.dst_port, [0, 0]);
1412
    /// assert_eq!(header.length, [0, 0]);
1413
    /// assert_eq!(header.checksum, [0, 0]);
1414
    /// ```
1415
    #[inline(always)]
1416
0
    fn zero(&mut self) {
1417
0
        let slf: *mut Self = self;
1418
0
        let len = mem::size_of_val(self);
1419
        // SAFETY:
1420
        // - `self` is guaranteed by the type system to be valid for writes of
1421
        //   size `size_of_val(self)`.
1422
        // - `u8`'s alignment is 1, and thus `self` is guaranteed to be aligned
1423
        //   as required by `u8`.
1424
        // - Since `Self: FromZeroes`, the all-zeroes instance is a valid
1425
        //   instance of `Self.`
1426
        //
1427
        // TODO(#429): Add references to docs and quotes.
1428
0
        unsafe { ptr::write_bytes(slf.cast::<u8>(), 0, len) };
1429
0
    }
1430
1431
    /// Creates an instance of `Self` from zeroed bytes.
1432
    ///
1433
    /// # Examples
1434
    ///
1435
    /// ```
1436
    /// # use zerocopy::FromZeroes;
1437
    /// # use zerocopy_derive::*;
1438
    /// #
1439
    /// #[derive(FromZeroes)]
1440
    /// #[repr(C)]
1441
    /// struct PacketHeader {
1442
    ///     src_port: [u8; 2],
1443
    ///     dst_port: [u8; 2],
1444
    ///     length: [u8; 2],
1445
    ///     checksum: [u8; 2],
1446
    /// }
1447
    ///
1448
    /// let header: PacketHeader = FromZeroes::new_zeroed();
1449
    ///
1450
    /// assert_eq!(header.src_port, [0, 0]);
1451
    /// assert_eq!(header.dst_port, [0, 0]);
1452
    /// assert_eq!(header.length, [0, 0]);
1453
    /// assert_eq!(header.checksum, [0, 0]);
1454
    /// ```
1455
    #[inline(always)]
1456
0
    fn new_zeroed() -> Self
1457
0
    where
1458
0
        Self: Sized,
1459
    {
1460
        // SAFETY: `FromZeroes` says that the all-zeroes bit pattern is legal.
1461
0
        unsafe { mem::zeroed() }
1462
0
    }
1463
1464
    /// Creates a `Box<Self>` from zeroed bytes.
1465
    ///
1466
    /// This function is useful for allocating large values on the heap and
1467
    /// zero-initializing them, without ever creating a temporary instance of
1468
    /// `Self` on the stack. For example, `<[u8; 1048576]>::new_box_zeroed()`
1469
    /// will allocate `[u8; 1048576]` directly on the heap; it does not require
1470
    /// storing `[u8; 1048576]` in a temporary variable on the stack.
1471
    ///
1472
    /// On systems that use a heap implementation that supports allocating from
1473
    /// pre-zeroed memory, using `new_box_zeroed` (or related functions) may
1474
    /// have performance benefits.
1475
    ///
1476
    /// Note that `Box<Self>` can be converted to `Arc<Self>` and other
1477
    /// container types without reallocation.
1478
    ///
1479
    /// # Panics
1480
    ///
1481
    /// Panics if allocation of `size_of::<Self>()` bytes fails.
1482
    #[cfg(feature = "alloc")]
1483
    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
1484
    #[inline]
1485
    fn new_box_zeroed() -> Box<Self>
1486
    where
1487
        Self: Sized,
1488
    {
1489
        // If `T` is a ZST, then return a proper boxed instance of it. There is
1490
        // no allocation, but `Box` does require a correct dangling pointer.
1491
        let layout = Layout::new::<Self>();
1492
        if layout.size() == 0 {
1493
            return Box::new(Self::new_zeroed());
1494
        }
1495
1496
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1497
        #[allow(clippy::undocumented_unsafe_blocks)]
1498
        let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
1499
        if ptr.is_null() {
1500
            alloc::alloc::handle_alloc_error(layout);
1501
        }
1502
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1503
        #[allow(clippy::undocumented_unsafe_blocks)]
1504
        unsafe {
1505
            Box::from_raw(ptr)
1506
        }
1507
    }
1508
1509
    /// Creates a `Box<[Self]>` (a boxed slice) from zeroed bytes.
1510
    ///
1511
    /// This function is useful for allocating large values of `[Self]` on the
1512
    /// heap and zero-initializing them, without ever creating a temporary
1513
    /// instance of `[Self; _]` on the stack. For example,
1514
    /// `u8::new_box_slice_zeroed(1048576)` will allocate the slice directly on
1515
    /// the heap; it does not require storing the slice on the stack.
1516
    ///
1517
    /// On systems that use a heap implementation that supports allocating from
1518
    /// pre-zeroed memory, using `new_box_slice_zeroed` may have performance
1519
    /// benefits.
1520
    ///
1521
    /// If `Self` is a zero-sized type, then this function will return a
1522
    /// `Box<[Self]>` that has the correct `len`. Such a box cannot contain any
1523
    /// actual information, but its `len()` property will report the correct
1524
    /// value.
1525
    ///
1526
    /// # Panics
1527
    ///
1528
    /// * Panics if `size_of::<Self>() * len` overflows.
1529
    /// * Panics if allocation of `size_of::<Self>() * len` bytes fails.
1530
    #[cfg(feature = "alloc")]
1531
    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
1532
    #[inline]
1533
    fn new_box_slice_zeroed(len: usize) -> Box<[Self]>
1534
    where
1535
        Self: Sized,
1536
    {
1537
        let size = mem::size_of::<Self>()
1538
            .checked_mul(len)
1539
            .expect("mem::size_of::<Self>() * len overflows `usize`");
1540
        let align = mem::align_of::<Self>();
1541
        // On stable Rust versions <= 1.64.0, `Layout::from_size_align` has a
1542
        // bug in which sufficiently-large allocations (those which, when
1543
        // rounded up to the alignment, overflow `isize`) are not rejected,
1544
        // which can cause undefined behavior. See #64 for details.
1545
        //
1546
        // TODO(#67): Once our MSRV is > 1.64.0, remove this assertion.
1547
        #[allow(clippy::as_conversions)]
1548
        let max_alloc = (isize::MAX as usize).saturating_sub(align);
1549
        assert!(size <= max_alloc);
1550
        // TODO(https://github.com/rust-lang/rust/issues/55724): Use
1551
        // `Layout::repeat` once it's stabilized.
1552
        let layout =
1553
            Layout::from_size_align(size, align).expect("total allocation size overflows `isize`");
1554
1555
        let ptr = if layout.size() != 0 {
1556
            // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1557
            #[allow(clippy::undocumented_unsafe_blocks)]
1558
            let ptr = unsafe { alloc::alloc::alloc_zeroed(layout).cast::<Self>() };
1559
            if ptr.is_null() {
1560
                alloc::alloc::handle_alloc_error(layout);
1561
            }
1562
            ptr
1563
        } else {
1564
            // `Box<[T]>` does not allocate when `T` is zero-sized or when `len`
1565
            // is zero, but it does require a non-null dangling pointer for its
1566
            // allocation.
1567
            NonNull::<Self>::dangling().as_ptr()
1568
        };
1569
1570
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
1571
        #[allow(clippy::undocumented_unsafe_blocks)]
1572
        unsafe {
1573
            Box::from_raw(slice::from_raw_parts_mut(ptr, len))
1574
        }
1575
    }
1576
1577
    /// Creates a `Vec<Self>` from zeroed bytes.
1578
    ///
1579
    /// This function is useful for allocating large values of `Vec`s and
1580
    /// zero-initializing them, without ever creating a temporary instance of
1581
    /// `[Self; _]` (or many temporary instances of `Self`) on the stack. For
1582
    /// example, `u8::new_vec_zeroed(1048576)` will allocate directly on the
1583
    /// heap; it does not require storing intermediate values on the stack.
1584
    ///
1585
    /// On systems that use a heap implementation that supports allocating from
1586
    /// pre-zeroed memory, using `new_vec_zeroed` may have performance benefits.
1587
    ///
1588
    /// If `Self` is a zero-sized type, then this function will return a
1589
    /// `Vec<Self>` that has the correct `len`. Such a `Vec` cannot contain any
1590
    /// actual information, but its `len()` property will report the correct
1591
    /// value.
1592
    ///
1593
    /// # Panics
1594
    ///
1595
    /// * Panics if `size_of::<Self>() * len` overflows.
1596
    /// * Panics if allocation of `size_of::<Self>() * len` bytes fails.
1597
    #[cfg(feature = "alloc")]
1598
    #[cfg_attr(doc_cfg, doc(cfg(feature = "new_vec_zeroed")))]
1599
    #[inline(always)]
1600
    fn new_vec_zeroed(len: usize) -> Vec<Self>
1601
    where
1602
        Self: Sized,
1603
    {
1604
        Self::new_box_slice_zeroed(len).into()
1605
    }
1606
}
1607
1608
/// Analyzes whether a type is [`FromBytes`].
1609
///
1610
/// This derive analyzes, at compile time, whether the annotated type satisfies
1611
/// the [safety conditions] of `FromBytes` and implements `FromBytes` if it is
1612
/// sound to do so. This derive can be applied to structs, enums, and unions;
1613
/// e.g.:
1614
///
1615
/// ```
1616
/// # use zerocopy_derive::{FromBytes, FromZeroes};
1617
/// #[derive(FromZeroes, FromBytes)]
1618
/// struct MyStruct {
1619
/// # /*
1620
///     ...
1621
/// # */
1622
/// }
1623
///
1624
/// #[derive(FromZeroes, FromBytes)]
1625
/// #[repr(u8)]
1626
/// enum MyEnum {
1627
/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
1628
/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
1629
/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
1630
/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
1631
/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
1632
/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
1633
/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
1634
/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
1635
/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
1636
/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
1637
/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
1638
/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
1639
/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
1640
/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
1641
/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
1642
/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
1643
/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
1644
/// #   VFF,
1645
/// # /*
1646
///     ...
1647
/// # */
1648
/// }
1649
///
1650
/// #[derive(FromZeroes, FromBytes)]
1651
/// union MyUnion {
1652
/// #   variant: u8,
1653
/// # /*
1654
///     ...
1655
/// # */
1656
/// }
1657
/// ```
1658
///
1659
/// [safety conditions]: trait@FromBytes#safety
1660
///
1661
/// # Analysis
1662
///
1663
/// *This section describes, roughly, the analysis performed by this derive to
1664
/// determine whether it is sound to implement `FromBytes` for a given type.
1665
/// Unless you are modifying the implementation of this derive, or attempting to
1666
/// manually implement `FromBytes` for a type yourself, you don't need to read
1667
/// this section.*
1668
///
1669
/// If a type has the following properties, then this derive can implement
1670
/// `FromBytes` for that type:
1671
///
1672
/// - If the type is a struct, all of its fields must be `FromBytes`.
1673
/// - If the type is an enum:
1674
///   - It must be a C-like enum (meaning that all variants have no fields).
1675
///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
1676
///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
1677
///   - The maximum number of discriminants must be used (so that every possible
1678
///     bit pattern is a valid one). Be very careful when using the `C`,
1679
///     `usize`, or `isize` representations, as their size is
1680
///     platform-dependent.
1681
/// - The type must not contain any [`UnsafeCell`]s (this is required in order
1682
///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
1683
///   memory). The type may contain references or pointers to `UnsafeCell`s so
1684
///   long as those values can themselves be initialized from zeroes
1685
///   (`FromBytes` is not currently implemented for, e.g., `Option<*const
1686
///   UnsafeCell<_>>`, but it could be one day).
1687
///
1688
/// [`UnsafeCell`]: core::cell::UnsafeCell
1689
///
1690
/// This analysis is subject to change. Unsafe code may *only* rely on the
1691
/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
1692
/// implementation details of this derive.
1693
///
1694
/// ## Why isn't an explicit representation required for structs?
1695
///
1696
/// Neither this derive, nor the [safety conditions] of `FromBytes`, requires
1697
/// that structs are marked with `#[repr(C)]`.
1698
///
1699
/// Per the [Rust reference](reference),
1700
///
1701
/// > The representation of a type can change the padding between fields, but
1702
/// does not change the layout of the fields themselves.
1703
///
1704
/// [reference]: https://doc.rust-lang.org/reference/type-layout.html#representations
1705
///
1706
/// Since the layout of structs only consists of padding bytes and field bytes,
1707
/// a struct is soundly `FromBytes` if:
1708
/// 1. its padding is soundly `FromBytes`, and
1709
/// 2. its fields are soundly `FromBytes`.
1710
///
1711
/// The answer to the first question is always yes: padding bytes do not have
1712
/// any validity constraints. A [discussion] of this question in the Unsafe Code
1713
/// Guidelines Working Group concluded that it would be virtually unimaginable
1714
/// for future versions of rustc to add validity constraints to padding bytes.
1715
///
1716
/// [discussion]: https://github.com/rust-lang/unsafe-code-guidelines/issues/174
1717
///
1718
/// Whether a struct is soundly `FromBytes` therefore solely depends on whether
1719
/// its fields are `FromBytes`.
1720
// TODO(#146): Document why we don't require an enum to have an explicit `repr`
1721
// attribute.
1722
#[cfg(any(feature = "derive", test))]
1723
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
1724
pub use zerocopy_derive::FromBytes;
1725
1726
/// Types for which any bit pattern is valid.
1727
///
1728
/// Any memory region of the appropriate length which contains initialized bytes
1729
/// can be viewed as any `FromBytes` type with no runtime overhead. This is
1730
/// useful for efficiently parsing bytes as structured data.
1731
///
1732
/// # Implementation
1733
///
1734
/// **Do not implement this trait yourself!** Instead, use
1735
/// [`#[derive(FromBytes)]`][derive] (requires the `derive` Cargo feature);
1736
/// e.g.:
1737
///
1738
/// ```
1739
/// # use zerocopy_derive::{FromBytes, FromZeroes};
1740
/// #[derive(FromZeroes, FromBytes)]
1741
/// struct MyStruct {
1742
/// # /*
1743
///     ...
1744
/// # */
1745
/// }
1746
///
1747
/// #[derive(FromZeroes, FromBytes)]
1748
/// #[repr(u8)]
1749
/// enum MyEnum {
1750
/// #   V00, V01, V02, V03, V04, V05, V06, V07, V08, V09, V0A, V0B, V0C, V0D, V0E,
1751
/// #   V0F, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V1A, V1B, V1C, V1D,
1752
/// #   V1E, V1F, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V2A, V2B, V2C,
1753
/// #   V2D, V2E, V2F, V30, V31, V32, V33, V34, V35, V36, V37, V38, V39, V3A, V3B,
1754
/// #   V3C, V3D, V3E, V3F, V40, V41, V42, V43, V44, V45, V46, V47, V48, V49, V4A,
1755
/// #   V4B, V4C, V4D, V4E, V4F, V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
1756
/// #   V5A, V5B, V5C, V5D, V5E, V5F, V60, V61, V62, V63, V64, V65, V66, V67, V68,
1757
/// #   V69, V6A, V6B, V6C, V6D, V6E, V6F, V70, V71, V72, V73, V74, V75, V76, V77,
1758
/// #   V78, V79, V7A, V7B, V7C, V7D, V7E, V7F, V80, V81, V82, V83, V84, V85, V86,
1759
/// #   V87, V88, V89, V8A, V8B, V8C, V8D, V8E, V8F, V90, V91, V92, V93, V94, V95,
1760
/// #   V96, V97, V98, V99, V9A, V9B, V9C, V9D, V9E, V9F, VA0, VA1, VA2, VA3, VA4,
1761
/// #   VA5, VA6, VA7, VA8, VA9, VAA, VAB, VAC, VAD, VAE, VAF, VB0, VB1, VB2, VB3,
1762
/// #   VB4, VB5, VB6, VB7, VB8, VB9, VBA, VBB, VBC, VBD, VBE, VBF, VC0, VC1, VC2,
1763
/// #   VC3, VC4, VC5, VC6, VC7, VC8, VC9, VCA, VCB, VCC, VCD, VCE, VCF, VD0, VD1,
1764
/// #   VD2, VD3, VD4, VD5, VD6, VD7, VD8, VD9, VDA, VDB, VDC, VDD, VDE, VDF, VE0,
1765
/// #   VE1, VE2, VE3, VE4, VE5, VE6, VE7, VE8, VE9, VEA, VEB, VEC, VED, VEE, VEF,
1766
/// #   VF0, VF1, VF2, VF3, VF4, VF5, VF6, VF7, VF8, VF9, VFA, VFB, VFC, VFD, VFE,
1767
/// #   VFF,
1768
/// # /*
1769
///     ...
1770
/// # */
1771
/// }
1772
///
1773
/// #[derive(FromZeroes, FromBytes)]
1774
/// union MyUnion {
1775
/// #   variant: u8,
1776
/// # /*
1777
///     ...
1778
/// # */
1779
/// }
1780
/// ```
1781
///
1782
/// This derive performs a sophisticated, compile-time safety analysis to
1783
/// determine whether a type is `FromBytes`.
1784
///
1785
/// # Safety
1786
///
1787
/// *This section describes what is required in order for `T: FromBytes`, and
1788
/// what unsafe code may assume of such types. If you don't plan on implementing
1789
/// `FromBytes` manually, and you don't plan on writing unsafe code that
1790
/// operates on `FromBytes` types, then you don't need to read this section.*
1791
///
1792
/// If `T: FromBytes`, then unsafe code may assume that:
1793
/// - It is sound to treat any initialized sequence of bytes of length
1794
///   `size_of::<T>()` as a `T`.
1795
/// - Given `b: &[u8]` where `b.len() == size_of::<T>()`, `b` is aligned to
1796
///   `align_of::<T>()` it is sound to construct a `t: &T` at the same address
1797
///   as `b`, and it is sound for both `b` and `t` to be live at the same time.
1798
///
1799
/// If a type is marked as `FromBytes` which violates this contract, it may
1800
/// cause undefined behavior.
1801
///
1802
/// `#[derive(FromBytes)]` only permits [types which satisfy these
1803
/// requirements][derive-analysis].
1804
///
1805
#[cfg_attr(
1806
    feature = "derive",
1807
    doc = "[derive]: zerocopy_derive::FromBytes",
1808
    doc = "[derive-analysis]: zerocopy_derive::FromBytes#analysis"
1809
)]
1810
#[cfg_attr(
1811
    not(feature = "derive"),
1812
    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html"),
1813
    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.FromBytes.html#analysis"),
1814
)]
1815
pub unsafe trait FromBytes: FromZeroes {
1816
    // The `Self: Sized` bound makes it so that `FromBytes` is still object
1817
    // safe.
1818
    #[doc(hidden)]
1819
    fn only_derive_is_allowed_to_implement_this_trait()
1820
    where
1821
        Self: Sized;
1822
1823
    /// Interprets the given `bytes` as a `&Self` without copying.
1824
    ///
1825
    /// If `bytes.len() != size_of::<Self>()` or `bytes` is not aligned to
1826
    /// `align_of::<Self>()`, this returns `None`.
1827
    ///
1828
    /// # Examples
1829
    ///
1830
    /// ```
1831
    /// use zerocopy::FromBytes;
1832
    /// # use zerocopy_derive::*;
1833
    ///
1834
    /// #[derive(FromZeroes, FromBytes)]
1835
    /// #[repr(C)]
1836
    /// struct PacketHeader {
1837
    ///     src_port: [u8; 2],
1838
    ///     dst_port: [u8; 2],
1839
    ///     length: [u8; 2],
1840
    ///     checksum: [u8; 2],
1841
    /// }
1842
    ///
1843
    /// // These bytes encode a `PacketHeader`.
1844
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
1845
    ///
1846
    /// let header = PacketHeader::ref_from(bytes).unwrap();
1847
    ///
1848
    /// assert_eq!(header.src_port, [0, 1]);
1849
    /// assert_eq!(header.dst_port, [2, 3]);
1850
    /// assert_eq!(header.length, [4, 5]);
1851
    /// assert_eq!(header.checksum, [6, 7]);
1852
    /// ```
1853
    #[inline]
1854
0
    fn ref_from(bytes: &[u8]) -> Option<&Self>
1855
0
    where
1856
0
        Self: Sized,
1857
    {
1858
0
        Ref::<&[u8], Self>::new(bytes).map(Ref::into_ref)
1859
0
    }
1860
1861
    /// Interprets the prefix of the given `bytes` as a `&Self` without copying.
1862
    ///
1863
    /// `ref_from_prefix` returns a reference to the first `size_of::<Self>()`
1864
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or `bytes` is not
1865
    /// aligned to `align_of::<Self>()`, this returns `None`.
1866
    ///
1867
    /// To also access the prefix bytes, use [`Ref::new_from_prefix`]. Then, use
1868
    /// [`Ref::into_ref`] to get a `&Self` with the same lifetime.
1869
    ///
1870
    /// # Examples
1871
    ///
1872
    /// ```
1873
    /// use zerocopy::FromBytes;
1874
    /// # use zerocopy_derive::*;
1875
    ///
1876
    /// #[derive(FromZeroes, FromBytes)]
1877
    /// #[repr(C)]
1878
    /// struct PacketHeader {
1879
    ///     src_port: [u8; 2],
1880
    ///     dst_port: [u8; 2],
1881
    ///     length: [u8; 2],
1882
    ///     checksum: [u8; 2],
1883
    /// }
1884
    ///
1885
    /// // These are more bytes than are needed to encode a `PacketHeader`.
1886
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
1887
    ///
1888
    /// let header = PacketHeader::ref_from_prefix(bytes).unwrap();
1889
    ///
1890
    /// assert_eq!(header.src_port, [0, 1]);
1891
    /// assert_eq!(header.dst_port, [2, 3]);
1892
    /// assert_eq!(header.length, [4, 5]);
1893
    /// assert_eq!(header.checksum, [6, 7]);
1894
    /// ```
1895
    #[inline]
1896
0
    fn ref_from_prefix(bytes: &[u8]) -> Option<&Self>
1897
0
    where
1898
0
        Self: Sized,
1899
    {
1900
0
        Ref::<&[u8], Self>::new_from_prefix(bytes).map(|(r, _)| r.into_ref())
1901
0
    }
1902
1903
    /// Interprets the suffix of the given `bytes` as a `&Self` without copying.
1904
    ///
1905
    /// `ref_from_suffix` returns a reference to the last `size_of::<Self>()`
1906
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or the suffix of
1907
    /// `bytes` is not aligned to `align_of::<Self>()`, this returns `None`.
1908
    ///
1909
    /// To also access the suffix bytes, use [`Ref::new_from_suffix`]. Then, use
1910
    /// [`Ref::into_ref`] to get a `&Self` with the same lifetime.
1911
    ///
1912
    /// # Examples
1913
    ///
1914
    /// ```
1915
    /// use zerocopy::FromBytes;
1916
    /// # use zerocopy_derive::*;
1917
    ///
1918
    /// #[derive(FromZeroes, FromBytes)]
1919
    /// #[repr(C)]
1920
    /// struct PacketTrailer {
1921
    ///     frame_check_sequence: [u8; 4],
1922
    /// }
1923
    ///
1924
    /// // These are more bytes than are needed to encode a `PacketTrailer`.
1925
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
1926
    ///
1927
    /// let trailer = PacketTrailer::ref_from_suffix(bytes).unwrap();
1928
    ///
1929
    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
1930
    /// ```
1931
    #[inline]
1932
0
    fn ref_from_suffix(bytes: &[u8]) -> Option<&Self>
1933
0
    where
1934
0
        Self: Sized,
1935
    {
1936
0
        Ref::<&[u8], Self>::new_from_suffix(bytes).map(|(_, r)| r.into_ref())
1937
0
    }
1938
1939
    /// Interprets the given `bytes` as a `&mut Self` without copying.
1940
    ///
1941
    /// If `bytes.len() != size_of::<Self>()` or `bytes` is not aligned to
1942
    /// `align_of::<Self>()`, this returns `None`.
1943
    ///
1944
    /// # Examples
1945
    ///
1946
    /// ```
1947
    /// use zerocopy::FromBytes;
1948
    /// # use zerocopy_derive::*;
1949
    ///
1950
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
1951
    /// #[repr(C)]
1952
    /// struct PacketHeader {
1953
    ///     src_port: [u8; 2],
1954
    ///     dst_port: [u8; 2],
1955
    ///     length: [u8; 2],
1956
    ///     checksum: [u8; 2],
1957
    /// }
1958
    ///
1959
    /// // These bytes encode a `PacketHeader`.
1960
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
1961
    ///
1962
    /// let header = PacketHeader::mut_from(bytes).unwrap();
1963
    ///
1964
    /// assert_eq!(header.src_port, [0, 1]);
1965
    /// assert_eq!(header.dst_port, [2, 3]);
1966
    /// assert_eq!(header.length, [4, 5]);
1967
    /// assert_eq!(header.checksum, [6, 7]);
1968
    ///
1969
    /// header.checksum = [0, 0];
1970
    ///
1971
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0]);
1972
    /// ```
1973
    #[inline]
1974
0
    fn mut_from(bytes: &mut [u8]) -> Option<&mut Self>
1975
0
    where
1976
0
        Self: Sized + AsBytes,
1977
    {
1978
0
        Ref::<&mut [u8], Self>::new(bytes).map(Ref::into_mut)
1979
0
    }
1980
1981
    /// Interprets the prefix of the given `bytes` as a `&mut Self` without
1982
    /// copying.
1983
    ///
1984
    /// `mut_from_prefix` returns a reference to the first `size_of::<Self>()`
1985
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or `bytes` is not
1986
    /// aligned to `align_of::<Self>()`, this returns `None`.
1987
    ///
1988
    /// To also access the prefix bytes, use [`Ref::new_from_prefix`]. Then, use
1989
    /// [`Ref::into_mut`] to get a `&mut Self` with the same lifetime.
1990
    ///
1991
    /// # Examples
1992
    ///
1993
    /// ```
1994
    /// use zerocopy::FromBytes;
1995
    /// # use zerocopy_derive::*;
1996
    ///
1997
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
1998
    /// #[repr(C)]
1999
    /// struct PacketHeader {
2000
    ///     src_port: [u8; 2],
2001
    ///     dst_port: [u8; 2],
2002
    ///     length: [u8; 2],
2003
    ///     checksum: [u8; 2],
2004
    /// }
2005
    ///
2006
    /// // These are more bytes than are needed to encode a `PacketHeader`.
2007
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2008
    ///
2009
    /// let header = PacketHeader::mut_from_prefix(bytes).unwrap();
2010
    ///
2011
    /// assert_eq!(header.src_port, [0, 1]);
2012
    /// assert_eq!(header.dst_port, [2, 3]);
2013
    /// assert_eq!(header.length, [4, 5]);
2014
    /// assert_eq!(header.checksum, [6, 7]);
2015
    ///
2016
    /// header.checksum = [0, 0];
2017
    ///
2018
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 8, 9]);
2019
    /// ```
2020
    #[inline]
2021
0
    fn mut_from_prefix(bytes: &mut [u8]) -> Option<&mut Self>
2022
0
    where
2023
0
        Self: Sized + AsBytes,
2024
    {
2025
0
        Ref::<&mut [u8], Self>::new_from_prefix(bytes).map(|(r, _)| r.into_mut())
2026
0
    }
2027
2028
    /// Interprets the suffix of the given `bytes` as a `&mut Self` without copying.
2029
    ///
2030
    /// `mut_from_suffix` returns a reference to the last `size_of::<Self>()`
2031
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()` or the suffix of
2032
    /// `bytes` is not aligned to `align_of::<Self>()`, this returns `None`.
2033
    ///
2034
    /// To also access the suffix bytes, use [`Ref::new_from_suffix`]. Then,
2035
    /// use [`Ref::into_mut`] to get a `&mut Self` with the same lifetime.
2036
    ///
2037
    /// # Examples
2038
    ///
2039
    /// ```
2040
    /// use zerocopy::FromBytes;
2041
    /// # use zerocopy_derive::*;
2042
    ///
2043
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2044
    /// #[repr(C)]
2045
    /// struct PacketTrailer {
2046
    ///     frame_check_sequence: [u8; 4],
2047
    /// }
2048
    ///
2049
    /// // These are more bytes than are needed to encode a `PacketTrailer`.
2050
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2051
    ///
2052
    /// let trailer = PacketTrailer::mut_from_suffix(bytes).unwrap();
2053
    ///
2054
    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
2055
    ///
2056
    /// trailer.frame_check_sequence = [0, 0, 0, 0];
2057
    ///
2058
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 0, 0]);
2059
    /// ```
2060
    #[inline]
2061
0
    fn mut_from_suffix(bytes: &mut [u8]) -> Option<&mut Self>
2062
0
    where
2063
0
        Self: Sized + AsBytes,
2064
    {
2065
0
        Ref::<&mut [u8], Self>::new_from_suffix(bytes).map(|(_, r)| r.into_mut())
2066
0
    }
2067
2068
    /// Interprets the given `bytes` as a `&[Self]` without copying.
2069
    ///
2070
    /// If `bytes.len() % size_of::<Self>() != 0` or `bytes` is not aligned to
2071
    /// `align_of::<Self>()`, this returns `None`.
2072
    ///
2073
    /// If you need to convert a specific number of slice elements, see
2074
    /// [`slice_from_prefix`](FromBytes::slice_from_prefix) or
2075
    /// [`slice_from_suffix`](FromBytes::slice_from_suffix).
2076
    ///
2077
    /// # Panics
2078
    ///
2079
    /// If `Self` is a zero-sized type.
2080
    ///
2081
    /// # Examples
2082
    ///
2083
    /// ```
2084
    /// use zerocopy::FromBytes;
2085
    /// # use zerocopy_derive::*;
2086
    ///
2087
    /// # #[derive(Debug, PartialEq, Eq)]
2088
    /// #[derive(FromZeroes, FromBytes)]
2089
    /// #[repr(C)]
2090
    /// struct Pixel {
2091
    ///     r: u8,
2092
    ///     g: u8,
2093
    ///     b: u8,
2094
    ///     a: u8,
2095
    /// }
2096
    ///
2097
    /// // These bytes encode two `Pixel`s.
2098
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
2099
    ///
2100
    /// let pixels = Pixel::slice_from(bytes).unwrap();
2101
    ///
2102
    /// assert_eq!(pixels, &[
2103
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2104
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2105
    /// ]);
2106
    /// ```
2107
    #[inline]
2108
0
    fn slice_from(bytes: &[u8]) -> Option<&[Self]>
2109
0
    where
2110
0
        Self: Sized,
2111
    {
2112
0
        Ref::<_, [Self]>::new_slice(bytes).map(|r| r.into_slice())
2113
0
    }
2114
2115
    /// Interprets the prefix of the given `bytes` as a `&[Self]` with length
2116
    /// equal to `count` without copying.
2117
    ///
2118
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2119
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2120
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a
2121
    /// `&[Self]`, and returns the remaining bytes to the caller. It also
2122
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2123
    /// If any of the length, alignment, or overflow checks fail, it returns
2124
    /// `None`.
2125
    ///
2126
    /// # Panics
2127
    ///
2128
    /// If `T` is a zero-sized type.
2129
    ///
2130
    /// # Examples
2131
    ///
2132
    /// ```
2133
    /// use zerocopy::FromBytes;
2134
    /// # use zerocopy_derive::*;
2135
    ///
2136
    /// # #[derive(Debug, PartialEq, Eq)]
2137
    /// #[derive(FromZeroes, FromBytes)]
2138
    /// #[repr(C)]
2139
    /// struct Pixel {
2140
    ///     r: u8,
2141
    ///     g: u8,
2142
    ///     b: u8,
2143
    ///     a: u8,
2144
    /// }
2145
    ///
2146
    /// // These are more bytes than are needed to encode two `Pixel`s.
2147
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2148
    ///
2149
    /// let (pixels, rest) = Pixel::slice_from_prefix(bytes, 2).unwrap();
2150
    ///
2151
    /// assert_eq!(pixels, &[
2152
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2153
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2154
    /// ]);
2155
    ///
2156
    /// assert_eq!(rest, &[8, 9]);
2157
    /// ```
2158
    #[inline]
2159
0
    fn slice_from_prefix(bytes: &[u8], count: usize) -> Option<(&[Self], &[u8])>
2160
0
    where
2161
0
        Self: Sized,
2162
    {
2163
0
        Ref::<_, [Self]>::new_slice_from_prefix(bytes, count).map(|(r, b)| (r.into_slice(), b))
2164
0
    }
2165
2166
    /// Interprets the suffix of the given `bytes` as a `&[Self]` with length
2167
    /// equal to `count` without copying.
2168
    ///
2169
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2170
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2171
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a
2172
    /// `&[Self]`, and returns the preceding bytes to the caller. It also
2173
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2174
    /// If any of the length, alignment, or overflow checks fail, it returns
2175
    /// `None`.
2176
    ///
2177
    /// # Panics
2178
    ///
2179
    /// If `T` is a zero-sized type.
2180
    ///
2181
    /// # Examples
2182
    ///
2183
    /// ```
2184
    /// use zerocopy::FromBytes;
2185
    /// # use zerocopy_derive::*;
2186
    ///
2187
    /// # #[derive(Debug, PartialEq, Eq)]
2188
    /// #[derive(FromZeroes, FromBytes)]
2189
    /// #[repr(C)]
2190
    /// struct Pixel {
2191
    ///     r: u8,
2192
    ///     g: u8,
2193
    ///     b: u8,
2194
    ///     a: u8,
2195
    /// }
2196
    ///
2197
    /// // These are more bytes than are needed to encode two `Pixel`s.
2198
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2199
    ///
2200
    /// let (rest, pixels) = Pixel::slice_from_suffix(bytes, 2).unwrap();
2201
    ///
2202
    /// assert_eq!(rest, &[0, 1]);
2203
    ///
2204
    /// assert_eq!(pixels, &[
2205
    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
2206
    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
2207
    /// ]);
2208
    /// ```
2209
    #[inline]
2210
0
    fn slice_from_suffix(bytes: &[u8], count: usize) -> Option<(&[u8], &[Self])>
2211
0
    where
2212
0
        Self: Sized,
2213
    {
2214
0
        Ref::<_, [Self]>::new_slice_from_suffix(bytes, count).map(|(b, r)| (b, r.into_slice()))
2215
0
    }
2216
2217
    /// Interprets the given `bytes` as a `&mut [Self]` without copying.
2218
    ///
2219
    /// If `bytes.len() % size_of::<T>() != 0` or `bytes` is not aligned to
2220
    /// `align_of::<T>()`, this returns `None`.
2221
    ///
2222
    /// If you need to convert a specific number of slice elements, see
2223
    /// [`mut_slice_from_prefix`](FromBytes::mut_slice_from_prefix) or
2224
    /// [`mut_slice_from_suffix`](FromBytes::mut_slice_from_suffix).
2225
    ///
2226
    /// # Panics
2227
    ///
2228
    /// If `T` is a zero-sized type.
2229
    ///
2230
    /// # Examples
2231
    ///
2232
    /// ```
2233
    /// use zerocopy::FromBytes;
2234
    /// # use zerocopy_derive::*;
2235
    ///
2236
    /// # #[derive(Debug, PartialEq, Eq)]
2237
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2238
    /// #[repr(C)]
2239
    /// struct Pixel {
2240
    ///     r: u8,
2241
    ///     g: u8,
2242
    ///     b: u8,
2243
    ///     a: u8,
2244
    /// }
2245
    ///
2246
    /// // These bytes encode two `Pixel`s.
2247
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7][..];
2248
    ///
2249
    /// let pixels = Pixel::mut_slice_from(bytes).unwrap();
2250
    ///
2251
    /// assert_eq!(pixels, &[
2252
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2253
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2254
    /// ]);
2255
    ///
2256
    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2257
    ///
2258
    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0]);
2259
    /// ```
2260
    #[inline]
2261
0
    fn mut_slice_from(bytes: &mut [u8]) -> Option<&mut [Self]>
2262
0
    where
2263
0
        Self: Sized + AsBytes,
2264
    {
2265
0
        Ref::<_, [Self]>::new_slice(bytes).map(|r| r.into_mut_slice())
2266
0
    }
2267
2268
    /// Interprets the prefix of the given `bytes` as a `&mut [Self]` with length
2269
    /// equal to `count` without copying.
2270
    ///
2271
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2272
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2273
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a
2274
    /// `&[Self]`, and returns the remaining bytes to the caller. It also
2275
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2276
    /// If any of the length, alignment, or overflow checks fail, it returns
2277
    /// `None`.
2278
    ///
2279
    /// # Panics
2280
    ///
2281
    /// If `T` is a zero-sized type.
2282
    ///
2283
    /// # Examples
2284
    ///
2285
    /// ```
2286
    /// use zerocopy::FromBytes;
2287
    /// # use zerocopy_derive::*;
2288
    ///
2289
    /// # #[derive(Debug, PartialEq, Eq)]
2290
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2291
    /// #[repr(C)]
2292
    /// struct Pixel {
2293
    ///     r: u8,
2294
    ///     g: u8,
2295
    ///     b: u8,
2296
    ///     a: u8,
2297
    /// }
2298
    ///
2299
    /// // These are more bytes than are needed to encode two `Pixel`s.
2300
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2301
    ///
2302
    /// let (pixels, rest) = Pixel::mut_slice_from_prefix(bytes, 2).unwrap();
2303
    ///
2304
    /// assert_eq!(pixels, &[
2305
    ///     Pixel { r: 0, g: 1, b: 2, a: 3 },
2306
    ///     Pixel { r: 4, g: 5, b: 6, a: 7 },
2307
    /// ]);
2308
    ///
2309
    /// assert_eq!(rest, &[8, 9]);
2310
    ///
2311
    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2312
    ///
2313
    /// assert_eq!(bytes, [0, 1, 2, 3, 0, 0, 0, 0, 8, 9]);
2314
    /// ```
2315
    #[inline]
2316
0
    fn mut_slice_from_prefix(bytes: &mut [u8], count: usize) -> Option<(&mut [Self], &mut [u8])>
2317
0
    where
2318
0
        Self: Sized + AsBytes,
2319
    {
2320
0
        Ref::<_, [Self]>::new_slice_from_prefix(bytes, count).map(|(r, b)| (r.into_mut_slice(), b))
2321
0
    }
2322
2323
    /// Interprets the suffix of the given `bytes` as a `&mut [Self]` with length
2324
    /// equal to `count` without copying.
2325
    ///
2326
    /// This method verifies that `bytes.len() >= size_of::<T>() * count`
2327
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the
2328
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a
2329
    /// `&[Self]`, and returns the preceding bytes to the caller. It also
2330
    /// ensures that `sizeof::<T>() * count` does not overflow a `usize`.
2331
    /// If any of the length, alignment, or overflow checks fail, it returns
2332
    /// `None`.
2333
    ///
2334
    /// # Panics
2335
    ///
2336
    /// If `T` is a zero-sized type.
2337
    ///
2338
    /// # Examples
2339
    ///
2340
    /// ```
2341
    /// use zerocopy::FromBytes;
2342
    /// # use zerocopy_derive::*;
2343
    ///
2344
    /// # #[derive(Debug, PartialEq, Eq)]
2345
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2346
    /// #[repr(C)]
2347
    /// struct Pixel {
2348
    ///     r: u8,
2349
    ///     g: u8,
2350
    ///     b: u8,
2351
    ///     a: u8,
2352
    /// }
2353
    ///
2354
    /// // These are more bytes than are needed to encode two `Pixel`s.
2355
    /// let bytes = &mut [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][..];
2356
    ///
2357
    /// let (rest, pixels) = Pixel::mut_slice_from_suffix(bytes, 2).unwrap();
2358
    ///
2359
    /// assert_eq!(rest, &[0, 1]);
2360
    ///
2361
    /// assert_eq!(pixels, &[
2362
    ///     Pixel { r: 2, g: 3, b: 4, a: 5 },
2363
    ///     Pixel { r: 6, g: 7, b: 8, a: 9 },
2364
    /// ]);
2365
    ///
2366
    /// pixels[1] = Pixel { r: 0, g: 0, b: 0, a: 0 };
2367
    ///
2368
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 0, 0, 0, 0]);
2369
    /// ```
2370
    #[inline]
2371
0
    fn mut_slice_from_suffix(bytes: &mut [u8], count: usize) -> Option<(&mut [u8], &mut [Self])>
2372
0
    where
2373
0
        Self: Sized + AsBytes,
2374
    {
2375
0
        Ref::<_, [Self]>::new_slice_from_suffix(bytes, count).map(|(b, r)| (b, r.into_mut_slice()))
2376
0
    }
2377
2378
    /// Reads a copy of `Self` from `bytes`.
2379
    ///
2380
    /// If `bytes.len() != size_of::<Self>()`, `read_from` returns `None`.
2381
    ///
2382
    /// # Examples
2383
    ///
2384
    /// ```
2385
    /// use zerocopy::FromBytes;
2386
    /// # use zerocopy_derive::*;
2387
    ///
2388
    /// #[derive(FromZeroes, FromBytes)]
2389
    /// #[repr(C)]
2390
    /// struct PacketHeader {
2391
    ///     src_port: [u8; 2],
2392
    ///     dst_port: [u8; 2],
2393
    ///     length: [u8; 2],
2394
    ///     checksum: [u8; 2],
2395
    /// }
2396
    ///
2397
    /// // These bytes encode a `PacketHeader`.
2398
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7].as_slice();
2399
    ///
2400
    /// let header = PacketHeader::read_from(bytes).unwrap();
2401
    ///
2402
    /// assert_eq!(header.src_port, [0, 1]);
2403
    /// assert_eq!(header.dst_port, [2, 3]);
2404
    /// assert_eq!(header.length, [4, 5]);
2405
    /// assert_eq!(header.checksum, [6, 7]);
2406
    /// ```
2407
    #[inline]
2408
0
    fn read_from(bytes: &[u8]) -> Option<Self>
2409
0
    where
2410
0
        Self: Sized,
2411
    {
2412
0
        Ref::<_, Unalign<Self>>::new_unaligned(bytes).map(|r| r.read().into_inner())
2413
0
    }
2414
2415
    /// Reads a copy of `Self` from the prefix of `bytes`.
2416
    ///
2417
    /// `read_from_prefix` reads a `Self` from the first `size_of::<Self>()`
2418
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
2419
    /// `None`.
2420
    ///
2421
    /// # Examples
2422
    ///
2423
    /// ```
2424
    /// use zerocopy::FromBytes;
2425
    /// # use zerocopy_derive::*;
2426
    ///
2427
    /// #[derive(FromZeroes, FromBytes)]
2428
    /// #[repr(C)]
2429
    /// struct PacketHeader {
2430
    ///     src_port: [u8; 2],
2431
    ///     dst_port: [u8; 2],
2432
    ///     length: [u8; 2],
2433
    ///     checksum: [u8; 2],
2434
    /// }
2435
    ///
2436
    /// // These are more bytes than are needed to encode a `PacketHeader`.
2437
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2438
    ///
2439
    /// let header = PacketHeader::read_from_prefix(bytes).unwrap();
2440
    ///
2441
    /// assert_eq!(header.src_port, [0, 1]);
2442
    /// assert_eq!(header.dst_port, [2, 3]);
2443
    /// assert_eq!(header.length, [4, 5]);
2444
    /// assert_eq!(header.checksum, [6, 7]);
2445
    /// ```
2446
    #[inline]
2447
0
    fn read_from_prefix(bytes: &[u8]) -> Option<Self>
2448
0
    where
2449
0
        Self: Sized,
2450
    {
2451
0
        Ref::<_, Unalign<Self>>::new_unaligned_from_prefix(bytes)
2452
0
            .map(|(r, _)| r.read().into_inner())
2453
0
    }
2454
2455
    /// Reads a copy of `Self` from the suffix of `bytes`.
2456
    ///
2457
    /// `read_from_suffix` reads a `Self` from the last `size_of::<Self>()`
2458
    /// bytes of `bytes`. If `bytes.len() < size_of::<Self>()`, it returns
2459
    /// `None`.
2460
    ///
2461
    /// # Examples
2462
    ///
2463
    /// ```
2464
    /// use zerocopy::FromBytes;
2465
    /// # use zerocopy_derive::*;
2466
    ///
2467
    /// #[derive(FromZeroes, FromBytes)]
2468
    /// #[repr(C)]
2469
    /// struct PacketTrailer {
2470
    ///     frame_check_sequence: [u8; 4],
2471
    /// }
2472
    ///
2473
    /// // These are more bytes than are needed to encode a `PacketTrailer`.
2474
    /// let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].as_slice();
2475
    ///
2476
    /// let trailer = PacketTrailer::read_from_suffix(bytes).unwrap();
2477
    ///
2478
    /// assert_eq!(trailer.frame_check_sequence, [6, 7, 8, 9]);
2479
    /// ```
2480
    #[inline]
2481
0
    fn read_from_suffix(bytes: &[u8]) -> Option<Self>
2482
0
    where
2483
0
        Self: Sized,
2484
    {
2485
0
        Ref::<_, Unalign<Self>>::new_unaligned_from_suffix(bytes)
2486
0
            .map(|(_, r)| r.read().into_inner())
2487
0
    }
2488
}
2489
2490
/// Analyzes whether a type is [`AsBytes`].
2491
///
2492
/// This derive analyzes, at compile time, whether the annotated type satisfies
2493
/// the [safety conditions] of `AsBytes` and implements `AsBytes` if it is
2494
/// sound to do so. This derive can be applied to structs, enums, and unions;
2495
/// e.g.:
2496
///
2497
/// ```
2498
/// # use zerocopy_derive::{AsBytes};
2499
/// #[derive(AsBytes)]
2500
/// #[repr(C)]
2501
/// struct MyStruct {
2502
/// # /*
2503
///     ...
2504
/// # */
2505
/// }
2506
///
2507
/// #[derive(AsBytes)]
2508
/// #[repr(u8)]
2509
/// enum MyEnum {
2510
/// #   Variant,
2511
/// # /*
2512
///     ...
2513
/// # */
2514
/// }
2515
///
2516
/// #[derive(AsBytes)]
2517
/// #[repr(C)]
2518
/// union MyUnion {
2519
/// #   variant: u8,
2520
/// # /*
2521
///     ...
2522
/// # */
2523
/// }
2524
/// ```
2525
///
2526
/// [safety conditions]: trait@AsBytes#safety
2527
///
2528
/// # Error Messages
2529
///
2530
/// Due to the way that the custom derive for `AsBytes` is implemented, you may
2531
/// get an error like this:
2532
///
2533
/// ```text
2534
/// error[E0277]: the trait bound `HasPadding<Foo, true>: ShouldBe<false>` is not satisfied
2535
///   --> lib.rs:23:10
2536
///    |
2537
///  1 | #[derive(AsBytes)]
2538
///    |          ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<Foo, true>`
2539
///    |
2540
///    = help: the trait `ShouldBe<VALUE>` is implemented for `HasPadding<T, VALUE>`
2541
/// ```
2542
///
2543
/// This error indicates that the type being annotated has padding bytes, which
2544
/// is illegal for `AsBytes` types. Consider reducing the alignment of some
2545
/// fields by using types in the [`byteorder`] module, adding explicit struct
2546
/// fields where those padding bytes would be, or using `#[repr(packed)]`. See
2547
/// the Rust Reference's page on [type layout] for more information
2548
/// about type layout and padding.
2549
///
2550
/// [type layout]: https://doc.rust-lang.org/reference/type-layout.html
2551
///
2552
/// # Analysis
2553
///
2554
/// *This section describes, roughly, the analysis performed by this derive to
2555
/// determine whether it is sound to implement `AsBytes` for a given type.
2556
/// Unless you are modifying the implementation of this derive, or attempting to
2557
/// manually implement `AsBytes` for a type yourself, you don't need to read
2558
/// this section.*
2559
///
2560
/// If a type has the following properties, then this derive can implement
2561
/// `AsBytes` for that type:
2562
///
2563
/// - If the type is a struct:
2564
///   - It must have a defined representation (`repr(C)`, `repr(transparent)`,
2565
///     or `repr(packed)`).
2566
///   - All of its fields must be `AsBytes`.
2567
///   - Its layout must have no padding. This is always true for
2568
///     `repr(transparent)` and `repr(packed)`. For `repr(C)`, see the layout
2569
///     algorithm described in the [Rust Reference].
2570
/// - If the type is an enum:
2571
///   - It must be a C-like enum (meaning that all variants have no fields).
2572
///   - It must have a defined representation (`repr`s `C`, `u8`, `u16`, `u32`,
2573
///     `u64`, `usize`, `i8`, `i16`, `i32`, `i64`, or `isize`).
2574
/// - The type must not contain any [`UnsafeCell`]s (this is required in order
2575
///   for it to be sound to construct a `&[u8]` and a `&T` to the same region of
2576
///   memory). The type may contain references or pointers to `UnsafeCell`s so
2577
///   long as those values can themselves be initialized from zeroes (`AsBytes`
2578
///   is not currently implemented for, e.g., `Option<&UnsafeCell<_>>`, but it
2579
///   could be one day).
2580
///
2581
/// [`UnsafeCell`]: core::cell::UnsafeCell
2582
///
2583
/// This analysis is subject to change. Unsafe code may *only* rely on the
2584
/// documented [safety conditions] of `FromBytes`, and must *not* rely on the
2585
/// implementation details of this derive.
2586
///
2587
/// [Rust Reference]: https://doc.rust-lang.org/reference/type-layout.html
2588
#[cfg(any(feature = "derive", test))]
2589
#[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))]
2590
pub use zerocopy_derive::AsBytes;
2591
2592
/// Types that can be viewed as an immutable slice of initialized bytes.
2593
///
2594
/// Any `AsBytes` type can be viewed as a slice of initialized bytes of the same
2595
/// size. This is useful for efficiently serializing structured data as raw
2596
/// bytes.
2597
///
2598
/// # Implementation
2599
///
2600
/// **Do not implement this trait yourself!** Instead, use
2601
/// [`#[derive(AsBytes)]`][derive] (requires the `derive` Cargo feature); e.g.:
2602
///
2603
/// ```
2604
/// # use zerocopy_derive::AsBytes;
2605
/// #[derive(AsBytes)]
2606
/// #[repr(C)]
2607
/// struct MyStruct {
2608
/// # /*
2609
///     ...
2610
/// # */
2611
/// }
2612
///
2613
/// #[derive(AsBytes)]
2614
/// #[repr(u8)]
2615
/// enum MyEnum {
2616
/// #   Variant0,
2617
/// # /*
2618
///     ...
2619
/// # */
2620
/// }
2621
///
2622
/// #[derive(AsBytes)]
2623
/// #[repr(C)]
2624
/// union MyUnion {
2625
/// #   variant: u8,
2626
/// # /*
2627
///     ...
2628
/// # */
2629
/// }
2630
/// ```
2631
///
2632
/// This derive performs a sophisticated, compile-time safety analysis to
2633
/// determine whether a type is `AsBytes`. See the [derive
2634
/// documentation][derive] for guidance on how to interpret error messages
2635
/// produced by the derive's analysis.
2636
///
2637
/// # Safety
2638
///
2639
/// *This section describes what is required in order for `T: AsBytes`, and
2640
/// what unsafe code may assume of such types. If you don't plan on implementing
2641
/// `AsBytes` manually, and you don't plan on writing unsafe code that
2642
/// operates on `AsBytes` types, then you don't need to read this section.*
2643
///
2644
/// If `T: AsBytes`, then unsafe code may assume that:
2645
/// - It is sound to treat any `t: T` as an immutable `[u8]` of length
2646
///   `size_of_val(t)`.
2647
/// - Given `t: &T`, it is sound to construct a `b: &[u8]` where `b.len() ==
2648
///   size_of_val(t)` at the same address as `t`, and it is sound for both `b`
2649
///   and `t` to be live at the same time.
2650
///
2651
/// If a type is marked as `AsBytes` which violates this contract, it may cause
2652
/// undefined behavior.
2653
///
2654
/// `#[derive(AsBytes)]` only permits [types which satisfy these
2655
/// requirements][derive-analysis].
2656
///
2657
#[cfg_attr(
2658
    feature = "derive",
2659
    doc = "[derive]: zerocopy_derive::AsBytes",
2660
    doc = "[derive-analysis]: zerocopy_derive::AsBytes#analysis"
2661
)]
2662
#[cfg_attr(
2663
    not(feature = "derive"),
2664
    doc = concat!("[derive]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.AsBytes.html"),
2665
    doc = concat!("[derive-analysis]: https://docs.rs/zerocopy/", env!("CARGO_PKG_VERSION"), "/zerocopy/derive.AsBytes.html#analysis"),
2666
)]
2667
pub unsafe trait AsBytes {
2668
    // The `Self: Sized` bound makes it so that this function doesn't prevent
2669
    // `AsBytes` from being object safe. Note that other `AsBytes` methods
2670
    // prevent object safety, but those provide a benefit in exchange for object
2671
    // safety. If at some point we remove those methods, change their type
2672
    // signatures, or move them out of this trait so that `AsBytes` is object
2673
    // safe again, it's important that this function not prevent object safety.
2674
    #[doc(hidden)]
2675
    fn only_derive_is_allowed_to_implement_this_trait()
2676
    where
2677
        Self: Sized;
2678
2679
    /// Gets the bytes of this value.
2680
    ///
2681
    /// `as_bytes` provides access to the bytes of this value as an immutable
2682
    /// byte slice.
2683
    ///
2684
    /// # Examples
2685
    ///
2686
    /// ```
2687
    /// use zerocopy::AsBytes;
2688
    /// # use zerocopy_derive::*;
2689
    ///
2690
    /// #[derive(AsBytes)]
2691
    /// #[repr(C)]
2692
    /// struct PacketHeader {
2693
    ///     src_port: [u8; 2],
2694
    ///     dst_port: [u8; 2],
2695
    ///     length: [u8; 2],
2696
    ///     checksum: [u8; 2],
2697
    /// }
2698
    ///
2699
    /// let header = PacketHeader {
2700
    ///     src_port: [0, 1],
2701
    ///     dst_port: [2, 3],
2702
    ///     length: [4, 5],
2703
    ///     checksum: [6, 7],
2704
    /// };
2705
    ///
2706
    /// let bytes = header.as_bytes();
2707
    ///
2708
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2709
    /// ```
2710
    #[inline(always)]
2711
0
    fn as_bytes(&self) -> &[u8] {
2712
        // Note that this method does not have a `Self: Sized` bound;
2713
        // `size_of_val` works for unsized values too.
2714
0
        let len = mem::size_of_val(self);
2715
0
        let slf: *const Self = self;
2716
2717
        // SAFETY:
2718
        // - `slf.cast::<u8>()` is valid for reads for `len *
2719
        //   mem::size_of::<u8>()` many bytes because...
2720
        //   - `slf` is the same pointer as `self`, and `self` is a reference
2721
        //     which points to an object whose size is `len`. Thus...
2722
        //     - The entire region of `len` bytes starting at `slf` is contained
2723
        //       within a single allocation.
2724
        //     - `slf` is non-null.
2725
        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
2726
        // - `Self: AsBytes` ensures that all of the bytes of `slf` are
2727
        //   initialized.
2728
        // - Since `slf` is derived from `self`, and `self` is an immutable
2729
        //   reference, the only other references to this memory region that
2730
        //   could exist are other immutable references, and those don't allow
2731
        //   mutation. `AsBytes` prohibits types which contain `UnsafeCell`s,
2732
        //   which are the only types for which this rule wouldn't be sufficient.
2733
        // - The total size of the resulting slice is no larger than
2734
        //   `isize::MAX` because no allocation produced by safe code can be
2735
        //   larger than `isize::MAX`.
2736
        //
2737
        // TODO(#429): Add references to docs and quotes.
2738
0
        unsafe { slice::from_raw_parts(slf.cast::<u8>(), len) }
2739
0
    }
Unexecuted instantiation: <[f32] as zerocopy::AsBytes>::as_bytes
Unexecuted instantiation: <_ as zerocopy::AsBytes>::as_bytes
2740
2741
    /// Gets the bytes of this value mutably.
2742
    ///
2743
    /// `as_bytes_mut` provides access to the bytes of this value as a mutable
2744
    /// byte slice.
2745
    ///
2746
    /// # Examples
2747
    ///
2748
    /// ```
2749
    /// use zerocopy::AsBytes;
2750
    /// # use zerocopy_derive::*;
2751
    ///
2752
    /// # #[derive(Eq, PartialEq, Debug)]
2753
    /// #[derive(AsBytes, FromZeroes, FromBytes)]
2754
    /// #[repr(C)]
2755
    /// struct PacketHeader {
2756
    ///     src_port: [u8; 2],
2757
    ///     dst_port: [u8; 2],
2758
    ///     length: [u8; 2],
2759
    ///     checksum: [u8; 2],
2760
    /// }
2761
    ///
2762
    /// let mut header = PacketHeader {
2763
    ///     src_port: [0, 1],
2764
    ///     dst_port: [2, 3],
2765
    ///     length: [4, 5],
2766
    ///     checksum: [6, 7],
2767
    /// };
2768
    ///
2769
    /// let bytes = header.as_bytes_mut();
2770
    ///
2771
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2772
    ///
2773
    /// bytes.reverse();
2774
    ///
2775
    /// assert_eq!(header, PacketHeader {
2776
    ///     src_port: [7, 6],
2777
    ///     dst_port: [5, 4],
2778
    ///     length: [3, 2],
2779
    ///     checksum: [1, 0],
2780
    /// });
2781
    /// ```
2782
    #[inline(always)]
2783
6
    fn as_bytes_mut(&mut self) -> &mut [u8]
2784
6
    where
2785
6
        Self: FromBytes,
2786
    {
2787
        // Note that this method does not have a `Self: Sized` bound;
2788
        // `size_of_val` works for unsized values too.
2789
6
        let len = mem::size_of_val(self);
2790
6
        let slf: *mut Self = self;
2791
2792
        // SAFETY:
2793
        // - `slf.cast::<u8>()` is valid for reads and writes for `len *
2794
        //   mem::size_of::<u8>()` many bytes because...
2795
        //   - `slf` is the same pointer as `self`, and `self` is a reference
2796
        //     which points to an object whose size is `len`. Thus...
2797
        //     - The entire region of `len` bytes starting at `slf` is contained
2798
        //       within a single allocation.
2799
        //     - `slf` is non-null.
2800
        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
2801
        // - `Self: AsBytes` ensures that all of the bytes of `slf` are
2802
        //   initialized.
2803
        // - `Self: FromBytes` ensures that no write to this memory region
2804
        //   could result in it containing an invalid `Self`.
2805
        // - Since `slf` is derived from `self`, and `self` is a mutable
2806
        //   reference, no other references to this memory region can exist.
2807
        // - The total size of the resulting slice is no larger than
2808
        //   `isize::MAX` because no allocation produced by safe code can be
2809
        //   larger than `isize::MAX`.
2810
        //
2811
        // TODO(#429): Add references to docs and quotes.
2812
6
        unsafe { slice::from_raw_parts_mut(slf.cast::<u8>(), len) }
2813
6
    }
Unexecuted instantiation: <[f32] as zerocopy::AsBytes>::as_bytes_mut
Unexecuted instantiation: <[i8; 128] as zerocopy::AsBytes>::as_bytes_mut
<[i8; 128] as zerocopy::AsBytes>::as_bytes_mut
Line
Count
Source
2783
6
    fn as_bytes_mut(&mut self) -> &mut [u8]
2784
6
    where
2785
6
        Self: FromBytes,
2786
    {
2787
        // Note that this method does not have a `Self: Sized` bound;
2788
        // `size_of_val` works for unsized values too.
2789
6
        let len = mem::size_of_val(self);
2790
6
        let slf: *mut Self = self;
2791
2792
        // SAFETY:
2793
        // - `slf.cast::<u8>()` is valid for reads and writes for `len *
2794
        //   mem::size_of::<u8>()` many bytes because...
2795
        //   - `slf` is the same pointer as `self`, and `self` is a reference
2796
        //     which points to an object whose size is `len`. Thus...
2797
        //     - The entire region of `len` bytes starting at `slf` is contained
2798
        //       within a single allocation.
2799
        //     - `slf` is non-null.
2800
        //   - `slf` is trivially aligned to `align_of::<u8>() == 1`.
2801
        // - `Self: AsBytes` ensures that all of the bytes of `slf` are
2802
        //   initialized.
2803
        // - `Self: FromBytes` ensures that no write to this memory region
2804
        //   could result in it containing an invalid `Self`.
2805
        // - Since `slf` is derived from `self`, and `self` is a mutable
2806
        //   reference, no other references to this memory region can exist.
2807
        // - The total size of the resulting slice is no larger than
2808
        //   `isize::MAX` because no allocation produced by safe code can be
2809
        //   larger than `isize::MAX`.
2810
        //
2811
        // TODO(#429): Add references to docs and quotes.
2812
6
        unsafe { slice::from_raw_parts_mut(slf.cast::<u8>(), len) }
2813
6
    }
Unexecuted instantiation: <_ as zerocopy::AsBytes>::as_bytes_mut
2814
2815
    /// Writes a copy of `self` to `bytes`.
2816
    ///
2817
    /// If `bytes.len() != size_of_val(self)`, `write_to` returns `None`.
2818
    ///
2819
    /// # Examples
2820
    ///
2821
    /// ```
2822
    /// use zerocopy::AsBytes;
2823
    /// # use zerocopy_derive::*;
2824
    ///
2825
    /// #[derive(AsBytes)]
2826
    /// #[repr(C)]
2827
    /// struct PacketHeader {
2828
    ///     src_port: [u8; 2],
2829
    ///     dst_port: [u8; 2],
2830
    ///     length: [u8; 2],
2831
    ///     checksum: [u8; 2],
2832
    /// }
2833
    ///
2834
    /// let header = PacketHeader {
2835
    ///     src_port: [0, 1],
2836
    ///     dst_port: [2, 3],
2837
    ///     length: [4, 5],
2838
    ///     checksum: [6, 7],
2839
    /// };
2840
    ///
2841
    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0];
2842
    ///
2843
    /// header.write_to(&mut bytes[..]);
2844
    ///
2845
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7]);
2846
    /// ```
2847
    ///
2848
    /// If too many or too few target bytes are provided, `write_to` returns
2849
    /// `None` and leaves the target bytes unmodified:
2850
    ///
2851
    /// ```
2852
    /// # use zerocopy::AsBytes;
2853
    /// # let header = u128::MAX;
2854
    /// let mut excessive_bytes = &mut [0u8; 128][..];
2855
    ///
2856
    /// let write_result = header.write_to(excessive_bytes);
2857
    ///
2858
    /// assert!(write_result.is_none());
2859
    /// assert_eq!(excessive_bytes, [0u8; 128]);
2860
    /// ```
2861
    #[inline]
2862
0
    fn write_to(&self, bytes: &mut [u8]) -> Option<()> {
2863
0
        if bytes.len() != mem::size_of_val(self) {
2864
0
            return None;
2865
0
        }
2866
2867
0
        bytes.copy_from_slice(self.as_bytes());
2868
0
        Some(())
2869
0
    }
2870
2871
    /// Writes a copy of `self` to the prefix of `bytes`.
2872
    ///
2873
    /// `write_to_prefix` writes `self` to the first `size_of_val(self)` bytes
2874
    /// of `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
2875
    ///
2876
    /// # Examples
2877
    ///
2878
    /// ```
2879
    /// use zerocopy::AsBytes;
2880
    /// # use zerocopy_derive::*;
2881
    ///
2882
    /// #[derive(AsBytes)]
2883
    /// #[repr(C)]
2884
    /// struct PacketHeader {
2885
    ///     src_port: [u8; 2],
2886
    ///     dst_port: [u8; 2],
2887
    ///     length: [u8; 2],
2888
    ///     checksum: [u8; 2],
2889
    /// }
2890
    ///
2891
    /// let header = PacketHeader {
2892
    ///     src_port: [0, 1],
2893
    ///     dst_port: [2, 3],
2894
    ///     length: [4, 5],
2895
    ///     checksum: [6, 7],
2896
    /// };
2897
    ///
2898
    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2899
    ///
2900
    /// header.write_to_prefix(&mut bytes[..]);
2901
    ///
2902
    /// assert_eq!(bytes, [0, 1, 2, 3, 4, 5, 6, 7, 0, 0]);
2903
    /// ```
2904
    ///
2905
    /// If insufficient target bytes are provided, `write_to_prefix` returns
2906
    /// `None` and leaves the target bytes unmodified:
2907
    ///
2908
    /// ```
2909
    /// # use zerocopy::AsBytes;
2910
    /// # let header = u128::MAX;
2911
    /// let mut insufficent_bytes = &mut [0, 0][..];
2912
    ///
2913
    /// let write_result = header.write_to_suffix(insufficent_bytes);
2914
    ///
2915
    /// assert!(write_result.is_none());
2916
    /// assert_eq!(insufficent_bytes, [0, 0]);
2917
    /// ```
2918
    #[inline]
2919
0
    fn write_to_prefix(&self, bytes: &mut [u8]) -> Option<()> {
2920
0
        let size = mem::size_of_val(self);
2921
0
        bytes.get_mut(..size)?.copy_from_slice(self.as_bytes());
2922
0
        Some(())
2923
0
    }
2924
2925
    /// Writes a copy of `self` to the suffix of `bytes`.
2926
    ///
2927
    /// `write_to_suffix` writes `self` to the last `size_of_val(self)` bytes of
2928
    /// `bytes`. If `bytes.len() < size_of_val(self)`, it returns `None`.
2929
    ///
2930
    /// # Examples
2931
    ///
2932
    /// ```
2933
    /// use zerocopy::AsBytes;
2934
    /// # use zerocopy_derive::*;
2935
    ///
2936
    /// #[derive(AsBytes)]
2937
    /// #[repr(C)]
2938
    /// struct PacketHeader {
2939
    ///     src_port: [u8; 2],
2940
    ///     dst_port: [u8; 2],
2941
    ///     length: [u8; 2],
2942
    ///     checksum: [u8; 2],
2943
    /// }
2944
    ///
2945
    /// let header = PacketHeader {
2946
    ///     src_port: [0, 1],
2947
    ///     dst_port: [2, 3],
2948
    ///     length: [4, 5],
2949
    ///     checksum: [6, 7],
2950
    /// };
2951
    ///
2952
    /// let mut bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2953
    ///
2954
    /// header.write_to_suffix(&mut bytes[..]);
2955
    ///
2956
    /// assert_eq!(bytes, [0, 0, 0, 1, 2, 3, 4, 5, 6, 7]);
2957
    ///
2958
    /// let mut insufficent_bytes = &mut [0, 0][..];
2959
    ///
2960
    /// let write_result = header.write_to_suffix(insufficent_bytes);
2961
    ///
2962
    /// assert!(write_result.is_none());
2963
    /// assert_eq!(insufficent_bytes, [0, 0]);
2964
    /// ```
2965
    ///
2966
    /// If insufficient target bytes are provided, `write_to_suffix` returns
2967
    /// `None` and leaves the target bytes unmodified:
2968
    ///
2969
    /// ```
2970
    /// # use zerocopy::AsBytes;
2971
    /// # let header = u128::MAX;
2972
    /// let mut insufficent_bytes = &mut [0, 0][..];
2973
    ///
2974
    /// let write_result = header.write_to_suffix(insufficent_bytes);
2975
    ///
2976
    /// assert!(write_result.is_none());
2977
    /// assert_eq!(insufficent_bytes, [0, 0]);
2978
    /// ```
2979
    #[inline]
2980
0
    fn write_to_suffix(&self, bytes: &mut [u8]) -> Option<()> {
2981
0
        let start = bytes.len().checked_sub(mem::size_of_val(self))?;
2982
0
        bytes
2983
0
            .get_mut(start..)
2984
0
            .expect("`start` should be in-bounds of `bytes`")
2985
0
            .copy_from_slice(self.as_bytes());
2986
0
        Some(())
2987
0
    }
2988
}
2989
2990
/// Types with no alignment requirement.
2991
///
2992
/// WARNING: Do not implement this trait yourself! Instead, use
2993
/// `#[derive(Unaligned)]` (requires the `derive` Cargo feature).
2994
///
2995
/// If `T: Unaligned`, then `align_of::<T>() == 1`.
2996
///
2997
/// # Safety
2998
///
2999
/// *This section describes what is required in order for `T: Unaligned`, and
3000
/// what unsafe code may assume of such types. `#[derive(Unaligned)]` only
3001
/// permits types which satisfy these requirements. If you don't plan on
3002
/// implementing `Unaligned` manually, and you don't plan on writing unsafe code
3003
/// that operates on `Unaligned` types, then you don't need to read this
3004
/// section.*
3005
///
3006
/// If `T: Unaligned`, then unsafe code may assume that it is sound to produce a
3007
/// reference to `T` at any memory location regardless of alignment. If a type
3008
/// is marked as `Unaligned` which violates this contract, it may cause
3009
/// undefined behavior.
3010
pub unsafe trait Unaligned {
3011
    // The `Self: Sized` bound makes it so that `Unaligned` is still object
3012
    // safe.
3013
    #[doc(hidden)]
3014
    fn only_derive_is_allowed_to_implement_this_trait()
3015
    where
3016
        Self: Sized;
3017
}
3018
3019
safety_comment! {
3020
    /// SAFETY:
3021
    /// Per the reference [1], "the unit tuple (`()`) ... is guaranteed as a
3022
    /// zero-sized type to have a size of 0 and an alignment of 1."
3023
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: There
3024
    ///   is only one possible sequence of 0 bytes, and `()` is inhabited.
3025
    /// - `AsBytes`: Since `()` has size 0, it contains no padding bytes.
3026
    /// - `Unaligned`: `()` has alignment 1.
3027
    ///
3028
    /// [1] https://doc.rust-lang.org/reference/type-layout.html#tuple-layout
3029
    unsafe_impl!((): TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3030
    assert_unaligned!(());
3031
}
3032
3033
safety_comment! {
3034
    /// SAFETY:
3035
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: all bit
3036
    ///   patterns are valid for numeric types [1]
3037
    /// - `AsBytes`: numeric types have no padding bytes [1]
3038
    /// - `Unaligned` (`u8` and `i8` only): The reference [2] specifies the size
3039
    ///   of `u8` and `i8` as 1 byte. We also know that:
3040
    ///   - Alignment is >= 1 [3]
3041
    ///   - Size is an integer multiple of alignment [4]
3042
    ///   - The only value >= 1 for which 1 is an integer multiple is 1
3043
    ///   Therefore, the only possible alignment for `u8` and `i8` is 1.
3044
    ///
3045
    /// [1] Per https://doc.rust-lang.org/beta/reference/types/numeric.html#bit-validity:
3046
    ///
3047
    ///     For every numeric type, `T`, the bit validity of `T` is equivalent to
3048
    ///     the bit validity of `[u8; size_of::<T>()]`. An uninitialized byte is
3049
    ///     not a valid `u8`.
3050
    ///
3051
    /// TODO(https://github.com/rust-lang/reference/pull/1392): Once this text
3052
    /// is available on the Stable docs, cite those instead.
3053
    ///
3054
    /// [2] https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout
3055
    ///
3056
    /// [3] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3057
    ///
3058
    ///     Alignment is measured in bytes, and must be at least 1.
3059
    ///
3060
    /// [4] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3061
    ///
3062
    ///     The size of a value is always a multiple of its alignment.
3063
    ///
3064
    /// TODO(#278): Once we've updated the trait docs to refer to `u8`s rather
3065
    /// than bits or bytes, update this comment, especially the reference to
3066
    /// [1].
3067
    unsafe_impl!(u8: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3068
    unsafe_impl!(i8: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3069
    assert_unaligned!(u8, i8);
3070
    unsafe_impl!(u16: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3071
    unsafe_impl!(i16: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3072
    unsafe_impl!(u32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3073
    unsafe_impl!(i32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3074
    unsafe_impl!(u64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3075
    unsafe_impl!(i64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3076
    unsafe_impl!(u128: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3077
    unsafe_impl!(i128: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3078
    unsafe_impl!(usize: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3079
    unsafe_impl!(isize: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3080
    unsafe_impl!(f32: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3081
    unsafe_impl!(f64: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3082
}
3083
3084
safety_comment! {
3085
    /// SAFETY:
3086
    /// - `FromZeroes`: Valid since "[t]he value false has the bit pattern
3087
    ///   0x00" [1].
3088
    /// - `AsBytes`: Since "the boolean type has a size and alignment of 1 each"
3089
    ///   and "The value false has the bit pattern 0x00 and the value true has
3090
    ///   the bit pattern 0x01" [1]. Thus, the only byte of the bool is always
3091
    ///   initialized.
3092
    /// - `Unaligned`: Per the reference [1], "[a]n object with the boolean type
3093
    ///   has a size and alignment of 1 each."
3094
    ///
3095
    /// [1] https://doc.rust-lang.org/reference/types/boolean.html
3096
    unsafe_impl!(bool: FromZeroes, AsBytes, Unaligned);
3097
    assert_unaligned!(bool);
3098
    /// SAFETY:
3099
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3100
    ///   closure:
3101
    ///   - Given `t: *mut bool` and `let r = *mut u8`, `r` refers to an object
3102
    ///     of the same size as that referred to by `t`. This is true because
3103
    ///     `bool` and `u8` have the same size (1 byte) [1].
3104
    ///   - Since the closure takes a `&u8` argument, given a `Ptr<'a, bool>`
3105
    ///     which satisfies the preconditions of
3106
    ///     `TryFromBytes::<bool>::is_bit_valid`, it must be guaranteed that the
3107
    ///     memory referenced by that `Ptr` always contains a valid `u8`. Since
3108
    ///     `bool`'s single byte is always initialized, `is_bit_valid`'s
3109
    ///     precondition requires that the same is true of its argument. Since
3110
    ///     `u8`'s only bit validity invariant is that its single byte must be
3111
    ///     initialized, this memory is guaranteed to contain a valid `u8`.
3112
    ///   - The alignment of `bool` is equal to the alignment of `u8`. [1] [2]
3113
    ///   - The impl must only return `true` for its argument if the original
3114
    ///     `Ptr<bool>` refers to a valid `bool`. We only return true if the
3115
    ///     `u8` value is 0 or 1, and both of these are valid values for `bool`.
3116
    ///     [3]
3117
    ///
3118
    /// [1] Per https://doc.rust-lang.org/reference/type-layout.html#primitive-data-layout:
3119
    ///
3120
    ///   The size of most primitives is given in this table.
3121
    ///
3122
    ///   | Type      | `size_of::<Type>() ` |
3123
    ///   |-----------|----------------------|
3124
    ///   | `bool`    | 1                    |
3125
    ///   | `u8`/`i8` | 1                    |
3126
    ///
3127
    /// [2] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
3128
    ///
3129
    ///   The size of a value is always a multiple of its alignment.
3130
    ///
3131
    /// [3] Per https://doc.rust-lang.org/reference/types/boolean.html:
3132
    ///
3133
    ///   The value false has the bit pattern 0x00 and the value true has the
3134
    ///   bit pattern 0x01.
3135
    unsafe_impl!(bool: TryFromBytes; |byte: &u8| *byte < 2);
3136
}
3137
safety_comment! {
3138
    /// SAFETY:
3139
    /// - `FromZeroes`: Per reference [1], "[a] value of type char is a Unicode
3140
    ///   scalar value (i.e. a code point that is not a surrogate), represented
3141
    ///   as a 32-bit unsigned word in the 0x0000 to 0xD7FF or 0xE000 to
3142
    ///   0x10FFFF range" which contains 0x0000.
3143
    /// - `AsBytes`: `char` is per reference [1] "represented as a 32-bit
3144
    ///   unsigned word" (`u32`) which is `AsBytes`. Note that unlike `u32`, not
3145
    ///   all bit patterns are valid for `char`.
3146
    ///
3147
    /// [1] https://doc.rust-lang.org/reference/types/textual.html
3148
    unsafe_impl!(char: FromZeroes, AsBytes);
3149
    /// SAFETY:
3150
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3151
    ///   closure:
3152
    ///   - Given `t: *mut char` and `let r = *mut u32`, `r` refers to an object
3153
    ///     of the same size as that referred to by `t`. This is true because
3154
    ///     `char` and `u32` have the same size [1].
3155
    ///   - Since the closure takes a `&u32` argument, given a `Ptr<'a, char>`
3156
    ///     which satisfies the preconditions of
3157
    ///     `TryFromBytes::<char>::is_bit_valid`, it must be guaranteed that the
3158
    ///     memory referenced by that `Ptr` always contains a valid `u32`. Since
3159
    ///     `char`'s bytes are always initialized [2], `is_bit_valid`'s
3160
    ///     precondition requires that the same is true of its argument. Since
3161
    ///     `u32`'s only bit validity invariant is that its bytes must be
3162
    ///     initialized, this memory is guaranteed to contain a valid `u32`.
3163
    ///   - The alignment of `char` is equal to the alignment of `u32`. [1]
3164
    ///   - The impl must only return `true` for its argument if the original
3165
    ///     `Ptr<char>` refers to a valid `char`. `char::from_u32` guarantees
3166
    ///     that it returns `None` if its input is not a valid `char`. [3]
3167
    ///
3168
    /// [1] Per https://doc.rust-lang.org/nightly/reference/types/textual.html#layout-and-bit-validity:
3169
    ///
3170
    ///   `char` is guaranteed to have the same size and alignment as `u32` on
3171
    ///   all platforms.
3172
    ///
3173
    /// [2] Per https://doc.rust-lang.org/core/primitive.char.html#method.from_u32:
3174
    ///
3175
    ///   Every byte of a `char` is guaranteed to be initialized.
3176
    ///
3177
    /// [3] Per https://doc.rust-lang.org/core/primitive.char.html#method.from_u32:
3178
    ///
3179
    ///   `from_u32()` will return `None` if the input is not a valid value for
3180
    ///   a `char`.
3181
    unsafe_impl!(char: TryFromBytes; |candidate: &u32| char::from_u32(*candidate).is_some());
3182
}
3183
safety_comment! {
3184
    /// SAFETY:
3185
    /// - `FromZeroes`, `AsBytes`, `Unaligned`: Per the reference [1], `str`
3186
    ///   has the same layout as `[u8]`, and `[u8]` is `FromZeroes`, `AsBytes`,
3187
    ///   and `Unaligned`.
3188
    ///
3189
    /// Note that we don't `assert_unaligned!(str)` because `assert_unaligned!`
3190
    /// uses `align_of`, which only works for `Sized` types.
3191
    ///
3192
    /// TODO(#429): Add quotes from documentation.
3193
    ///
3194
    /// [1] https://doc.rust-lang.org/reference/type-layout.html#str-layout
3195
    unsafe_impl!(str: FromZeroes, AsBytes, Unaligned);
3196
    /// SAFETY:
3197
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3198
    ///   closure:
3199
    ///   - Given `t: *mut str` and `let r = *mut [u8]`, `r` refers to an object
3200
    ///     of the same size as that referred to by `t`. This is true because
3201
    ///     `str` and `[u8]` have the same representation. [1]
3202
    ///   - Since the closure takes a `&[u8]` argument, given a `Ptr<'a, str>`
3203
    ///     which satisfies the preconditions of
3204
    ///     `TryFromBytes::<str>::is_bit_valid`, it must be guaranteed that the
3205
    ///     memory referenced by that `Ptr` always contains a valid `[u8]`.
3206
    ///     Since `str`'s bytes are always initialized [1], `is_bit_valid`'s
3207
    ///     precondition requires that the same is true of its argument. Since
3208
    ///     `[u8]`'s only bit validity invariant is that its bytes must be
3209
    ///     initialized, this memory is guaranteed to contain a valid `[u8]`.
3210
    ///   - The alignment of `str` is equal to the alignment of `[u8]`. [1]
3211
    ///   - The impl must only return `true` for its argument if the original
3212
    ///     `Ptr<str>` refers to a valid `str`. `str::from_utf8` guarantees that
3213
    ///     it returns `Err` if its input is not a valid `str`. [2]
3214
    ///
3215
    /// [1] Per https://doc.rust-lang.org/reference/types/textual.html:
3216
    ///
3217
    ///   A value of type `str` is represented the same was as `[u8]`.
3218
    ///
3219
    /// [2] Per https://doc.rust-lang.org/core/str/fn.from_utf8.html#errors:
3220
    ///
3221
    ///   Returns `Err` if the slice is not UTF-8.
3222
    unsafe_impl!(str: TryFromBytes; |candidate: &[u8]| core::str::from_utf8(candidate).is_ok());
3223
}
3224
3225
safety_comment! {
3226
    // `NonZeroXxx` is `AsBytes`, but not `FromZeroes` or `FromBytes`.
3227
    //
3228
    /// SAFETY:
3229
    /// - `AsBytes`: `NonZeroXxx` has the same layout as its associated
3230
    ///    primitive. Since it is the same size, this guarantees it has no
3231
    ///    padding - integers have no padding, and there's no room for padding
3232
    ///    if it can represent all of the same values except 0.
3233
    /// - `Unaligned`: `NonZeroU8` and `NonZeroI8` document that
3234
    ///   `Option<NonZeroU8>` and `Option<NonZeroI8>` both have size 1. [1] [2]
3235
    ///   This is worded in a way that makes it unclear whether it's meant as a
3236
    ///   guarantee, but given the purpose of those types, it's virtually
3237
    ///   unthinkable that that would ever change. `Option` cannot be smaller
3238
    ///   than its contained type, which implies that, and `NonZeroX8` are of
3239
    ///   size 1 or 0. `NonZeroX8` can represent multiple states, so they cannot
3240
    ///   be 0 bytes, which means that they must be 1 byte. The only valid
3241
    ///   alignment for a 1-byte type is 1.
3242
    ///
3243
    /// TODO(#429): Add quotes from documentation.
3244
    ///
3245
    /// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
3246
    /// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
3247
    /// TODO(https://github.com/rust-lang/rust/pull/104082): Cite documentation
3248
    /// that layout is the same as primitive layout.
3249
    unsafe_impl!(NonZeroU8: AsBytes, Unaligned);
3250
    unsafe_impl!(NonZeroI8: AsBytes, Unaligned);
3251
    assert_unaligned!(NonZeroU8, NonZeroI8);
3252
    unsafe_impl!(NonZeroU16: AsBytes);
3253
    unsafe_impl!(NonZeroI16: AsBytes);
3254
    unsafe_impl!(NonZeroU32: AsBytes);
3255
    unsafe_impl!(NonZeroI32: AsBytes);
3256
    unsafe_impl!(NonZeroU64: AsBytes);
3257
    unsafe_impl!(NonZeroI64: AsBytes);
3258
    unsafe_impl!(NonZeroU128: AsBytes);
3259
    unsafe_impl!(NonZeroI128: AsBytes);
3260
    unsafe_impl!(NonZeroUsize: AsBytes);
3261
    unsafe_impl!(NonZeroIsize: AsBytes);
3262
    /// SAFETY:
3263
    /// - The safety requirements for `unsafe_impl!` with an `is_bit_valid`
3264
    ///   closure:
3265
    ///   - Given `t: *mut NonZeroXxx` and `let r = *mut xxx`, `r` refers to an
3266
    ///     object of the same size as that referred to by `t`. This is true
3267
    ///     because `NonZeroXxx` and `xxx` have the same size. [1]
3268
    ///   - Since the closure takes a `&xxx` argument, given a `Ptr<'a,
3269
    ///     NonZeroXxx>` which satisfies the preconditions of
3270
    ///     `TryFromBytes::<NonZeroXxx>::is_bit_valid`, it must be guaranteed
3271
    ///     that the memory referenced by that `Ptr` always contains a valid
3272
    ///     `xxx`. Since `NonZeroXxx`'s bytes are always initialized [1],
3273
    ///     `is_bit_valid`'s precondition requires that the same is true of its
3274
    ///     argument. Since `xxx`'s only bit validity invariant is that its
3275
    ///     bytes must be initialized, this memory is guaranteed to contain a
3276
    ///     valid `xxx`.
3277
    ///   - The alignment of `NonZeroXxx` is equal to the alignment of `xxx`.
3278
    ///     [1]
3279
    ///   - The impl must only return `true` for its argument if the original
3280
    ///     `Ptr<NonZeroXxx>` refers to a valid `NonZeroXxx`. The only `xxx`
3281
    ///     which is not also a valid `NonZeroXxx` is 0. [1]
3282
    ///
3283
    /// [1] Per https://doc.rust-lang.org/core/num/struct.NonZeroU16.html:
3284
    ///
3285
    ///   `NonZeroU16` is guaranteed to have the same layout and bit validity as
3286
    ///   `u16` with the exception that `0` is not a valid instance.
3287
    unsafe_impl!(NonZeroU8: TryFromBytes; |n: &u8| *n != 0);
3288
    unsafe_impl!(NonZeroI8: TryFromBytes; |n: &i8| *n != 0);
3289
    unsafe_impl!(NonZeroU16: TryFromBytes; |n: &u16| *n != 0);
3290
    unsafe_impl!(NonZeroI16: TryFromBytes; |n: &i16| *n != 0);
3291
    unsafe_impl!(NonZeroU32: TryFromBytes; |n: &u32| *n != 0);
3292
    unsafe_impl!(NonZeroI32: TryFromBytes; |n: &i32| *n != 0);
3293
    unsafe_impl!(NonZeroU64: TryFromBytes; |n: &u64| *n != 0);
3294
    unsafe_impl!(NonZeroI64: TryFromBytes; |n: &i64| *n != 0);
3295
    unsafe_impl!(NonZeroU128: TryFromBytes; |n: &u128| *n != 0);
3296
    unsafe_impl!(NonZeroI128: TryFromBytes; |n: &i128| *n != 0);
3297
    unsafe_impl!(NonZeroUsize: TryFromBytes; |n: &usize| *n != 0);
3298
    unsafe_impl!(NonZeroIsize: TryFromBytes; |n: &isize| *n != 0);
3299
}
3300
safety_comment! {
3301
    /// SAFETY:
3302
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`,
3303
    ///   `AsBytes`: The Rust compiler reuses `0` value to represent `None`, so
3304
    ///   `size_of::<Option<NonZeroXxx>>() == size_of::<xxx>()`; see
3305
    ///   `NonZeroXxx` documentation.
3306
    /// - `Unaligned`: `NonZeroU8` and `NonZeroI8` document that
3307
    ///   `Option<NonZeroU8>` and `Option<NonZeroI8>` both have size 1. [1] [2]
3308
    ///   This is worded in a way that makes it unclear whether it's meant as a
3309
    ///   guarantee, but given the purpose of those types, it's virtually
3310
    ///   unthinkable that that would ever change. The only valid alignment for
3311
    ///   a 1-byte type is 1.
3312
    ///
3313
    /// TODO(#429): Add quotes from documentation.
3314
    ///
3315
    /// [1] https://doc.rust-lang.org/stable/std/num/struct.NonZeroU8.html
3316
    /// [2] https://doc.rust-lang.org/stable/std/num/struct.NonZeroI8.html
3317
    ///
3318
    /// TODO(https://github.com/rust-lang/rust/pull/104082): Cite documentation
3319
    /// for layout guarantees.
3320
    unsafe_impl!(Option<NonZeroU8>: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3321
    unsafe_impl!(Option<NonZeroI8>: TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
3322
    assert_unaligned!(Option<NonZeroU8>, Option<NonZeroI8>);
3323
    unsafe_impl!(Option<NonZeroU16>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3324
    unsafe_impl!(Option<NonZeroI16>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3325
    unsafe_impl!(Option<NonZeroU32>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3326
    unsafe_impl!(Option<NonZeroI32>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3327
    unsafe_impl!(Option<NonZeroU64>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3328
    unsafe_impl!(Option<NonZeroI64>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3329
    unsafe_impl!(Option<NonZeroU128>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3330
    unsafe_impl!(Option<NonZeroI128>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3331
    unsafe_impl!(Option<NonZeroUsize>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3332
    unsafe_impl!(Option<NonZeroIsize>: TryFromBytes, FromZeroes, FromBytes, AsBytes);
3333
}
3334
3335
safety_comment! {
3336
    /// SAFETY:
3337
    /// The following types can be transmuted from `[0u8; size_of::<T>()]`. [1]
3338
    /// None of them contain `UnsafeCell`s, and so they all soundly implement
3339
    /// `FromZeroes`.
3340
    ///
3341
    /// [1] Per
3342
    /// https://doc.rust-lang.org/nightly/core/option/index.html#representation:
3343
    ///
3344
    ///   Rust guarantees to optimize the following types `T` such that
3345
    ///   [`Option<T>`] has the same size and alignment as `T`. In some of these
3346
    ///   cases, Rust further guarantees that `transmute::<_, Option<T>>([0u8;
3347
    ///   size_of::<T>()])` is sound and produces `Option::<T>::None`. These
3348
    ///   cases are identified by the second column:
3349
    ///
3350
    ///   | `T`                   | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
3351
    ///   |-----------------------|-----------------------------------------------------------|
3352
    ///   | [`Box<U>`]            | when `U: Sized`                                           |
3353
    ///   | `&U`                  | when `U: Sized`                                           |
3354
    ///   | `&mut U`              | when `U: Sized`                                           |
3355
    ///   | [`ptr::NonNull<U>`]   | when `U: Sized`                                           |
3356
    ///   | `fn`, `extern "C" fn` | always                                                    |
3357
    ///
3358
    /// TODO(#429), TODO(https://github.com/rust-lang/rust/pull/115333): Cite
3359
    /// the Stable docs once they're available.
3360
    #[cfg(feature = "alloc")]
3361
    unsafe_impl!(
3362
        #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
3363
        T => FromZeroes for Option<Box<T>>
3364
    );
3365
    unsafe_impl!(T => FromZeroes for Option<&'_ T>);
3366
    unsafe_impl!(T => FromZeroes for Option<&'_ mut T>);
3367
    unsafe_impl!(T => FromZeroes for Option<NonNull<T>>);
3368
    unsafe_impl_for_power_set!(A, B, C, D, E, F, G, H, I, J, K, L -> M => FromZeroes for opt_fn!(...));
3369
    unsafe_impl_for_power_set!(A, B, C, D, E, F, G, H, I, J, K, L -> M => FromZeroes for opt_extern_c_fn!(...));
3370
}
3371
3372
safety_comment! {
3373
    /// SAFETY:
3374
    /// Per reference [1]:
3375
    /// "For all T, the following are guaranteed:
3376
    /// size_of::<PhantomData<T>>() == 0
3377
    /// align_of::<PhantomData<T>>() == 1".
3378
    /// This gives:
3379
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`: There
3380
    ///   is only one possible sequence of 0 bytes, and `PhantomData` is
3381
    ///   inhabited.
3382
    /// - `AsBytes`: Since `PhantomData` has size 0, it contains no padding
3383
    ///   bytes.
3384
    /// - `Unaligned`: Per the preceding reference, `PhantomData` has alignment
3385
    ///   1.
3386
    ///
3387
    /// [1] https://doc.rust-lang.org/std/marker/struct.PhantomData.html#layout-1
3388
    unsafe_impl!(T: ?Sized => TryFromBytes for PhantomData<T>);
3389
    unsafe_impl!(T: ?Sized => FromZeroes for PhantomData<T>);
3390
    unsafe_impl!(T: ?Sized => FromBytes for PhantomData<T>);
3391
    unsafe_impl!(T: ?Sized => AsBytes for PhantomData<T>);
3392
    unsafe_impl!(T: ?Sized => Unaligned for PhantomData<T>);
3393
    assert_unaligned!(PhantomData<()>, PhantomData<u8>, PhantomData<u64>);
3394
}
3395
safety_comment! {
3396
    /// SAFETY:
3397
    /// `Wrapping<T>` is guaranteed by its docs [1] to have the same layout and
3398
    /// bit validity as `T`. Also, `Wrapping<T>` is `#[repr(transparent)]`, and
3399
    /// has a single field, which is `pub`. Per the reference [2], this means
3400
    /// that the `#[repr(transparent)]` attribute is "considered part of the
3401
    /// public ABI".
3402
    ///
3403
    /// - `TryFromBytes`: The safety requirements for `unsafe_impl!` with an
3404
    ///   `is_bit_valid` closure:
3405
    ///   - Given `t: *mut Wrapping<T>` and `let r = *mut T`, `r` refers to an
3406
    ///     object of the same size as that referred to by `t`. This is true
3407
    ///     because `Wrapping<T>` and `T` have the same layout
3408
    ///   - The alignment of `Wrapping<T>` is equal to the alignment of `T`.
3409
    ///   - The impl must only return `true` for its argument if the original
3410
    ///     `Ptr<Wrapping<T>>` refers to a valid `Wrapping<T>`. Since
3411
    ///     `Wrapping<T>` has the same bit validity as `T`, and since our impl
3412
    ///     just calls `T::is_bit_valid`, our impl returns `true` exactly when
3413
    ///     its argument contains a valid `Wrapping<T>`.
3414
    /// - `FromBytes`: Since `Wrapping<T>` has the same bit validity as `T`, if
3415
    ///   `T: FromBytes`, then all initialized byte sequences are valid
3416
    ///   instances of `Wrapping<T>`. Similarly, if `T: FromBytes`, then
3417
    ///   `Wrapping<T>` doesn't contain any `UnsafeCell`s. Thus, `impl FromBytes
3418
    ///   for Wrapping<T> where T: FromBytes` is a sound impl.
3419
    /// - `AsBytes`: Since `Wrapping<T>` has the same bit validity as `T`, if
3420
    ///   `T: AsBytes`, then all valid instances of `Wrapping<T>` have all of
3421
    ///   their bytes initialized. Similarly, if `T: AsBytes`, then
3422
    ///   `Wrapping<T>` doesn't contain any `UnsafeCell`s. Thus, `impl AsBytes
3423
    ///   for Wrapping<T> where T: AsBytes` is a valid impl.
3424
    /// - `Unaligned`: Since `Wrapping<T>` has the same layout as `T`,
3425
    ///   `Wrapping<T>` has alignment 1 exactly when `T` does.
3426
    ///
3427
    /// [1] Per https://doc.rust-lang.org/core/num/struct.NonZeroU16.html:
3428
    ///
3429
    ///   `NonZeroU16` is guaranteed to have the same layout and bit validity as
3430
    ///   `u16` with the exception that `0` is not a valid instance.
3431
    ///
3432
    /// TODO(#429): Add quotes from documentation.
3433
    ///
3434
    /// [1] TODO(https://doc.rust-lang.org/nightly/core/num/struct.Wrapping.html#layout-1):
3435
    /// Reference this documentation once it's available on stable.
3436
    ///
3437
    /// [2] https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
3438
    unsafe_impl!(T: TryFromBytes => TryFromBytes for Wrapping<T>; |candidate: Ptr<T>| {
3439
        // SAFETY:
3440
        // - Since `T` and `Wrapping<T>` have the same layout and bit validity
3441
        //   and contain the same fields, `T` contains `UnsafeCell`s exactly
3442
        //   where `Wrapping<T>` does. Thus, all memory and `UnsafeCell`
3443
        //   preconditions of `T::is_bit_valid` hold exactly when the same
3444
        //   preconditions for `Wrapping<T>::is_bit_valid` hold.
3445
        // - By the same token, since `candidate` is guaranteed to have its
3446
        //   bytes initialized where there are always initialized bytes in
3447
        //   `Wrapping<T>`, the same is true for `T`.
3448
        unsafe { T::is_bit_valid(candidate) }
3449
    });
3450
    unsafe_impl!(T: FromZeroes => FromZeroes for Wrapping<T>);
3451
    unsafe_impl!(T: FromBytes => FromBytes for Wrapping<T>);
3452
    unsafe_impl!(T: AsBytes => AsBytes for Wrapping<T>);
3453
    unsafe_impl!(T: Unaligned => Unaligned for Wrapping<T>);
3454
    assert_unaligned!(Wrapping<()>, Wrapping<u8>);
3455
}
3456
safety_comment! {
3457
    // `MaybeUninit<T>` is `FromZeroes` and `FromBytes`, but never `AsBytes`
3458
    // since it may contain uninitialized bytes.
3459
    //
3460
    /// SAFETY:
3461
    /// - `TryFromBytes` (with no validator), `FromZeroes`, `FromBytes`:
3462
    ///   `MaybeUninit<T>` has no restrictions on its contents. Unfortunately,
3463
    ///   in addition to bit validity, `TryFromBytes`, `FromZeroes` and
3464
    ///   `FromBytes` also require that implementers contain no `UnsafeCell`s.
3465
    ///   Thus, we require `T: Trait` in order to ensure that `T` - and thus
3466
    ///   `MaybeUninit<T>` - contains to `UnsafeCell`s. Thus, requiring that `T`
3467
    ///   implement each of these traits is sufficient.
3468
    /// - `Unaligned`: "MaybeUninit<T> is guaranteed to have the same size,
3469
    ///    alignment, and ABI as T" [1]
3470
    ///
3471
    /// [1] https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#layout-1
3472
    ///
3473
    /// TODO(https://github.com/google/zerocopy/issues/251): If we split
3474
    /// `FromBytes` and `RefFromBytes`, or if we introduce a separate
3475
    /// `NoCell`/`Freeze` trait, we can relax the trait bounds for `FromZeroes`
3476
    /// and `FromBytes`.
3477
    unsafe_impl!(T: TryFromBytes => TryFromBytes for MaybeUninit<T>);
3478
    unsafe_impl!(T: FromZeroes => FromZeroes for MaybeUninit<T>);
3479
    unsafe_impl!(T: FromBytes => FromBytes for MaybeUninit<T>);
3480
    unsafe_impl!(T: Unaligned => Unaligned for MaybeUninit<T>);
3481
    assert_unaligned!(MaybeUninit<()>, MaybeUninit<u8>);
3482
}
3483
safety_comment! {
3484
    /// SAFETY:
3485
    /// `ManuallyDrop` has the same layout and bit validity as `T` [1], and
3486
    /// accessing the inner value is safe (meaning that it's unsound to leave
3487
    /// the inner value uninitialized while exposing the `ManuallyDrop` to safe
3488
    /// code).
3489
    /// - `FromZeroes`, `FromBytes`: Since it has the same layout as `T`, any
3490
    ///   valid `T` is a valid `ManuallyDrop<T>`. If `T: FromZeroes`, a sequence
3491
    ///   of zero bytes is a valid `T`, and thus a valid `ManuallyDrop<T>`. If
3492
    ///   `T: FromBytes`, any sequence of bytes is a valid `T`, and thus a valid
3493
    ///   `ManuallyDrop<T>`.
3494
    /// - `AsBytes`: Since it has the same layout as `T`, and since it's unsound
3495
    ///   to let safe code access a `ManuallyDrop` whose inner value is
3496
    ///   uninitialized, safe code can only ever access a `ManuallyDrop` whose
3497
    ///   contents are a valid `T`. Since `T: AsBytes`, this means that safe
3498
    ///   code can only ever access a `ManuallyDrop` with all initialized bytes.
3499
    /// - `Unaligned`: `ManuallyDrop` has the same layout (and thus alignment)
3500
    ///   as `T`, and `T: Unaligned` guarantees that that alignment is 1.
3501
    ///
3502
    ///   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
3503
    ///   validity as `T`
3504
    ///
3505
    /// [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
3506
    ///
3507
    /// TODO(#429):
3508
    /// - Add quotes from docs.
3509
    /// - Once [1] (added in
3510
    /// https://github.com/rust-lang/rust/pull/115522) is available on stable,
3511
    /// quote the stable docs instead of the nightly docs.
3512
    unsafe_impl!(T: ?Sized + FromZeroes => FromZeroes for ManuallyDrop<T>);
3513
    unsafe_impl!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>);
3514
    unsafe_impl!(T: ?Sized + AsBytes => AsBytes for ManuallyDrop<T>);
3515
    unsafe_impl!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>);
3516
    assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
3517
}
3518
safety_comment! {
3519
    /// SAFETY:
3520
    /// Per the reference [1]:
3521
    ///
3522
    ///   An array of `[T; N]` has a size of `size_of::<T>() * N` and the same
3523
    ///   alignment of `T`. Arrays are laid out so that the zero-based `nth`
3524
    ///   element of the array is offset from the start of the array by `n *
3525
    ///   size_of::<T>()` bytes.
3526
    ///
3527
    ///   ...
3528
    ///
3529
    ///   Slices have the same layout as the section of the array they slice.
3530
    ///
3531
    /// In other words, the layout of a `[T]` or `[T; N]` is a sequence of `T`s
3532
    /// laid out back-to-back with no bytes in between. Therefore, `[T]` or `[T;
3533
    /// N]` are `TryFromBytes`, `FromZeroes`, `FromBytes`, and `AsBytes` if `T`
3534
    /// is (respectively). Furthermore, since an array/slice has "the same
3535
    /// alignment of `T`", `[T]` and `[T; N]` are `Unaligned` if `T` is.
3536
    ///
3537
    /// Note that we don't `assert_unaligned!` for slice types because
3538
    /// `assert_unaligned!` uses `align_of`, which only works for `Sized` types.
3539
    ///
3540
    /// [1] https://doc.rust-lang.org/reference/type-layout.html#array-layout
3541
    unsafe_impl!(const N: usize, T: FromZeroes => FromZeroes for [T; N]);
3542
    unsafe_impl!(const N: usize, T: FromBytes => FromBytes for [T; N]);
3543
    unsafe_impl!(const N: usize, T: AsBytes => AsBytes for [T; N]);
3544
    unsafe_impl!(const N: usize, T: Unaligned => Unaligned for [T; N]);
3545
    assert_unaligned!([(); 0], [(); 1], [u8; 0], [u8; 1]);
3546
    unsafe_impl!(T: TryFromBytes => TryFromBytes for [T]; |c: Ptr<[T]>| {
3547
        // SAFETY: Assuming the preconditions of `is_bit_valid` are satisfied,
3548
        // so too will the postcondition: that, if `is_bit_valid(candidate)`
3549
        // returns true, `*candidate` contains a valid `Self`. Per the reference
3550
        // [1]:
3551
        //
3552
        //   An array of `[T; N]` has a size of `size_of::<T>() * N` and the
3553
        //   same alignment of `T`. Arrays are laid out so that the zero-based
3554
        //   `nth` element of the array is offset from the start of the array by
3555
        //   `n * size_of::<T>()` bytes.
3556
        //
3557
        //   ...
3558
        //
3559
        //   Slices have the same layout as the section of the array they slice.
3560
        //
3561
        // In other words, the layout of a `[T] is a sequence of `T`s laid out
3562
        // back-to-back with no bytes in between. If all elements in `candidate`
3563
        // are `is_bit_valid`, so too is `candidate`.
3564
        //
3565
        // Note that any of the below calls may panic, but it would still be
3566
        // sound even if it did. `is_bit_valid` does not promise that it will
3567
        // not panic (in fact, it explicitly warns that it's a possibility), and
3568
        // we have not violated any safety invariants that we must fix before
3569
        // returning.
3570
        c.iter().all(|elem|
3571
            // SAFETY: We uphold the safety contract of `is_bit_valid(elem)`, by
3572
            // precondition on the surrounding call to `is_bit_valid`. The
3573
            // memory referenced by `elem` is contained entirely within `c`, and
3574
            // satisfies the preconditions satisfied by `c`. By axiom, we assume
3575
            // that `Iterator:all` does not invalidate these preconditions
3576
            // (e.g., by writing to `elem`.) Since `elem` is derived from `c`,
3577
            // it is only possible for uninitialized bytes to occur in `elem` at
3578
            // the same bytes they occur within `c`.
3579
0
            unsafe { <T as TryFromBytes>::is_bit_valid(elem) }
3580
        )
3581
    });
3582
    unsafe_impl!(T: FromZeroes => FromZeroes for [T]);
3583
    unsafe_impl!(T: FromBytes => FromBytes for [T]);
3584
    unsafe_impl!(T: AsBytes => AsBytes for [T]);
3585
    unsafe_impl!(T: Unaligned => Unaligned for [T]);
3586
}
3587
safety_comment! {
3588
    /// SAFETY:
3589
    /// - `FromZeroes`: For thin pointers (note that `T: Sized`), the zero
3590
    ///   pointer is considered "null". [1] No operations which require
3591
    ///   provenance are legal on null pointers, so this is not a footgun.
3592
    ///
3593
    /// NOTE(#170): Implementing `FromBytes` and `AsBytes` for raw pointers
3594
    /// would be sound, but carries provenance footguns. We want to support
3595
    /// `FromBytes` and `AsBytes` for raw pointers eventually, but we are
3596
    /// holding off until we can figure out how to address those footguns.
3597
    ///
3598
    /// [1] TODO(https://github.com/rust-lang/rust/pull/116988): Cite the
3599
    /// documentation once this PR lands.
3600
    unsafe_impl!(T => FromZeroes for *const T);
3601
    unsafe_impl!(T => FromZeroes for *mut T);
3602
}
3603
3604
// SIMD support
3605
//
3606
// Per the Unsafe Code Guidelines Reference [1]:
3607
//
3608
//   Packed SIMD vector types are `repr(simd)` homogeneous tuple-structs
3609
//   containing `N` elements of type `T` where `N` is a power-of-two and the
3610
//   size and alignment requirements of `T` are equal:
3611
//
3612
//   ```rust
3613
//   #[repr(simd)]
3614
//   struct Vector<T, N>(T_0, ..., T_(N - 1));
3615
//   ```
3616
//
3617
//   ...
3618
//
3619
//   The size of `Vector` is `N * size_of::<T>()` and its alignment is an
3620
//   implementation-defined function of `T` and `N` greater than or equal to
3621
//   `align_of::<T>()`.
3622
//
3623
//   ...
3624
//
3625
//   Vector elements are laid out in source field order, enabling random access
3626
//   to vector elements by reinterpreting the vector as an array:
3627
//
3628
//   ```rust
3629
//   union U {
3630
//      vec: Vector<T, N>,
3631
//      arr: [T; N]
3632
//   }
3633
//
3634
//   assert_eq!(size_of::<Vector<T, N>>(), size_of::<[T; N]>());
3635
//   assert!(align_of::<Vector<T, N>>() >= align_of::<[T; N]>());
3636
//
3637
//   unsafe {
3638
//     let u = U { vec: Vector<T, N>(t_0, ..., t_(N - 1)) };
3639
//
3640
//     assert_eq!(u.vec.0, u.arr[0]);
3641
//     // ...
3642
//     assert_eq!(u.vec.(N - 1), u.arr[N - 1]);
3643
//   }
3644
//   ```
3645
//
3646
// Given this background, we can observe that:
3647
// - The size and bit pattern requirements of a SIMD type are equivalent to the
3648
//   equivalent array type. Thus, for any SIMD type whose primitive `T` is
3649
//   `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes`, that SIMD type is
3650
//   also `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes` respectively.
3651
// - Since no upper bound is placed on the alignment, no SIMD type can be
3652
//   guaranteed to be `Unaligned`.
3653
//
3654
// Also per [1]:
3655
//
3656
//   This chapter represents the consensus from issue #38. The statements in
3657
//   here are not (yet) "guaranteed" not to change until an RFC ratifies them.
3658
//
3659
// See issue #38 [2]. While this behavior is not technically guaranteed, the
3660
// likelihood that the behavior will change such that SIMD types are no longer
3661
// `TryFromBytes`, `FromZeroes`, `FromBytes`, or `AsBytes` is next to zero, as
3662
// that would defeat the entire purpose of SIMD types. Nonetheless, we put this
3663
// behavior behind the `simd` Cargo feature, which requires consumers to opt
3664
// into this stability hazard.
3665
//
3666
// [1] https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html
3667
// [2] https://github.com/rust-lang/unsafe-code-guidelines/issues/38
3668
#[cfg(feature = "simd")]
3669
#[cfg_attr(doc_cfg, doc(cfg(feature = "simd")))]
3670
mod simd {
3671
    /// Defines a module which implements `TryFromBytes`, `FromZeroes`,
3672
    /// `FromBytes`, and `AsBytes` for a set of types from a module in
3673
    /// `core::arch`.
3674
    ///
3675
    /// `$arch` is both the name of the defined module and the name of the
3676
    /// module in `core::arch`, and `$typ` is the list of items from that module
3677
    /// to implement `FromZeroes`, `FromBytes`, and `AsBytes` for.
3678
    #[allow(unused_macros)] // `allow(unused_macros)` is needed because some
3679
                            // target/feature combinations don't emit any impls
3680
                            // and thus don't use this macro.
3681
    macro_rules! simd_arch_mod {
3682
        (#[cfg $cfg:tt] $arch:ident, $mod:ident, $($typ:ident),*) => {
3683
            #[cfg $cfg]
3684
            #[cfg_attr(doc_cfg, doc(cfg $cfg))]
3685
            mod $mod {
3686
                use core::arch::$arch::{$($typ),*};
3687
3688
                use crate::*;
3689
                impl_known_layout!($($typ),*);
3690
                safety_comment! {
3691
                    /// SAFETY:
3692
                    /// See comment on module definition for justification.
3693
                    $( unsafe_impl!($typ: TryFromBytes, FromZeroes, FromBytes, AsBytes); )*
3694
                }
3695
            }
3696
        };
3697
    }
3698
3699
    #[rustfmt::skip]
3700
    const _: () = {
3701
        simd_arch_mod!(
3702
            #[cfg(target_arch = "x86")]
3703
            x86, x86, __m128, __m128d, __m128i, __m256, __m256d, __m256i
3704
        );
3705
        simd_arch_mod!(
3706
            #[cfg(all(feature = "simd-nightly", target_arch = "x86"))]
3707
            x86, x86_nightly, __m512bh, __m512, __m512d, __m512i
3708
        );
3709
        simd_arch_mod!(
3710
            #[cfg(target_arch = "x86_64")]
3711
            x86_64, x86_64, __m128, __m128d, __m128i, __m256, __m256d, __m256i
3712
        );
3713
        simd_arch_mod!(
3714
            #[cfg(all(feature = "simd-nightly", target_arch = "x86_64"))]
3715
            x86_64, x86_64_nightly, __m512bh, __m512, __m512d, __m512i
3716
        );
3717
        simd_arch_mod!(
3718
            #[cfg(target_arch = "wasm32")]
3719
            wasm32, wasm32, v128
3720
        );
3721
        simd_arch_mod!(
3722
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc"))]
3723
            powerpc, powerpc, vector_bool_long, vector_double, vector_signed_long, vector_unsigned_long
3724
        );
3725
        simd_arch_mod!(
3726
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc64"))]
3727
            powerpc64, powerpc64, vector_bool_long, vector_double, vector_signed_long, vector_unsigned_long
3728
        );
3729
        simd_arch_mod!(
3730
            #[cfg(target_arch = "aarch64")]
3731
            aarch64, aarch64, float32x2_t, float32x4_t, float64x1_t, float64x2_t, int8x8_t, int8x8x2_t,
3732
            int8x8x3_t, int8x8x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int16x4_t,
3733
            int16x8_t, int32x2_t, int32x4_t, int64x1_t, int64x2_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t,
3734
            poly8x8x4_t, poly8x16_t, poly8x16x2_t, poly8x16x3_t, poly8x16x4_t, poly16x4_t, poly16x8_t,
3735
            poly64x1_t, poly64x2_t, uint8x8_t, uint8x8x2_t, uint8x8x3_t, uint8x8x4_t, uint8x16_t,
3736
            uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint16x4_t, uint16x8_t, uint32x2_t, uint32x4_t,
3737
            uint64x1_t, uint64x2_t
3738
        );
3739
        simd_arch_mod!(
3740
            #[cfg(all(feature = "simd-nightly", target_arch = "arm"))]
3741
            arm, arm, int8x4_t, uint8x4_t
3742
        );
3743
    };
3744
}
3745
3746
/// Safely transmutes a value of one type to a value of another type of the same
3747
/// size.
3748
///
3749
/// The expression `$e` must have a concrete type, `T`, which implements
3750
/// `AsBytes`. The `transmute!` expression must also have a concrete type, `U`
3751
/// (`U` is inferred from the calling context), and `U` must implement
3752
/// `FromBytes`.
3753
///
3754
/// Note that the `T` produced by the expression `$e` will *not* be dropped.
3755
/// Semantically, its bits will be copied into a new value of type `U`, the
3756
/// original `T` will be forgotten, and the value of type `U` will be returned.
3757
///
3758
/// # Examples
3759
///
3760
/// ```
3761
/// # use zerocopy::transmute;
3762
/// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3763
///
3764
/// let two_dimensional: [[u8; 4]; 2] = transmute!(one_dimensional);
3765
///
3766
/// assert_eq!(two_dimensional, [[0, 1, 2, 3], [4, 5, 6, 7]]);
3767
/// ```
3768
#[macro_export]
3769
macro_rules! transmute {
3770
    ($e:expr) => {{
3771
        // NOTE: This must be a macro (rather than a function with trait bounds)
3772
        // because there's no way, in a generic context, to enforce that two
3773
        // types have the same size. `core::mem::transmute` uses compiler magic
3774
        // to enforce this so long as the types are concrete.
3775
3776
        let e = $e;
3777
        if false {
3778
            // This branch, though never taken, ensures that the type of `e` is
3779
            // `AsBytes` and that the type of this macro invocation expression
3780
            // is `FromBytes`.
3781
3782
            struct AssertIsAsBytes<T: $crate::AsBytes>(T);
3783
            let _ = AssertIsAsBytes(e);
3784
3785
            struct AssertIsFromBytes<U: $crate::FromBytes>(U);
3786
            #[allow(unused, unreachable_code)]
3787
            let u = AssertIsFromBytes(loop {});
3788
            u.0
3789
        } else {
3790
            // SAFETY: `core::mem::transmute` ensures that the type of `e` and
3791
            // the type of this macro invocation expression have the same size.
3792
            // We know this transmute is safe thanks to the `AsBytes` and
3793
            // `FromBytes` bounds enforced by the `false` branch.
3794
            //
3795
            // We use this reexport of `core::mem::transmute` because we know it
3796
            // will always be available for crates which are using the 2015
3797
            // edition of Rust. By contrast, if we were to use
3798
            // `std::mem::transmute`, this macro would not work for such crates
3799
            // in `no_std` contexts, and if we were to use
3800
            // `core::mem::transmute`, this macro would not work in `std`
3801
            // contexts in which `core` was not manually imported. This is not a
3802
            // problem for 2018 edition crates.
3803
            unsafe {
3804
                // Clippy: It's okay to transmute a type to itself.
3805
                #[allow(clippy::useless_transmute, clippy::missing_transmute_annotations)]
3806
                $crate::macro_util::core_reexport::mem::transmute(e)
3807
            }
3808
        }
3809
    }}
3810
}
3811
3812
/// Safely transmutes a mutable or immutable reference of one type to an
3813
/// immutable reference of another type of the same size.
3814
///
3815
/// The expression `$e` must have a concrete type, `&T` or `&mut T`, where `T:
3816
/// Sized + AsBytes`. The `transmute_ref!` expression must also have a concrete
3817
/// type, `&U` (`U` is inferred from the calling context), where `U: Sized +
3818
/// FromBytes`. It must be the case that `align_of::<T>() >= align_of::<U>()`.
3819
///
3820
/// The lifetime of the input type, `&T` or `&mut T`, must be the same as or
3821
/// outlive the lifetime of the output type, `&U`.
3822
///
3823
/// # Examples
3824
///
3825
/// ```
3826
/// # use zerocopy::transmute_ref;
3827
/// let one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3828
///
3829
/// let two_dimensional: &[[u8; 4]; 2] = transmute_ref!(&one_dimensional);
3830
///
3831
/// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);
3832
/// ```
3833
///
3834
/// # Alignment increase error message
3835
///
3836
/// Because of limitations on macros, the error message generated when
3837
/// `transmute_ref!` is used to transmute from a type of lower alignment to a
3838
/// type of higher alignment is somewhat confusing. For example, the following
3839
/// code:
3840
///
3841
/// ```compile_fail
3842
/// const INCREASE_ALIGNMENT: &u16 = zerocopy::transmute_ref!(&[0u8; 2]);
3843
/// ```
3844
///
3845
/// ...generates the following error:
3846
///
3847
/// ```text
3848
/// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
3849
///  --> src/lib.rs:1524:34
3850
///   |
3851
/// 5 | const INCREASE_ALIGNMENT: &u16 = zerocopy::transmute_ref!(&[0u8; 2]);
3852
///   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3853
///   |
3854
///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)
3855
///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
3856
///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `transmute_ref` (in Nightly builds, run with -Z macro-backtrace for more info)
3857
/// ```
3858
///
3859
/// This is saying that `max(align_of::<T>(), align_of::<U>()) !=
3860
/// align_of::<T>()`, which is equivalent to `align_of::<T>() <
3861
/// align_of::<U>()`.
3862
#[macro_export]
3863
macro_rules! transmute_ref {
3864
    ($e:expr) => {{
3865
        // NOTE: This must be a macro (rather than a function with trait bounds)
3866
        // because there's no way, in a generic context, to enforce that two
3867
        // types have the same size or alignment.
3868
3869
        // Ensure that the source type is a reference or a mutable reference
3870
        // (note that mutable references are implicitly reborrowed here).
3871
        let e: &_ = $e;
3872
3873
        #[allow(unused, clippy::diverging_sub_expression)]
3874
        if false {
3875
            // This branch, though never taken, ensures that the type of `e` is
3876
            // `&T` where `T: 't + Sized + AsBytes`, that the type of this macro
3877
            // expression is `&U` where `U: 'u + Sized + FromBytes`, and that
3878
            // `'t` outlives `'u`.
3879
3880
            struct AssertIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
3881
            let _ = AssertIsAsBytes(e);
3882
3883
            struct AssertIsFromBytes<'a, U: ::core::marker::Sized + $crate::FromBytes>(&'a U);
3884
            #[allow(unused, unreachable_code)]
3885
            let u = AssertIsFromBytes(loop {});
3886
            u.0
3887
        } else if false {
3888
            // This branch, though never taken, ensures that `size_of::<T>() ==
3889
            // size_of::<U>()` and that that `align_of::<T>() >=
3890
            // align_of::<U>()`.
3891
3892
            // `t` is inferred to have type `T` because it's assigned to `e` (of
3893
            // type `&T`) as `&t`.
3894
            let mut t = unreachable!();
3895
            e = &t;
3896
3897
            // `u` is inferred to have type `U` because it's used as `&u` as the
3898
            // value returned from this branch.
3899
            let u;
3900
3901
            $crate::assert_size_eq!(t, u);
3902
            $crate::assert_align_gt_eq!(t, u);
3903
3904
            &u
3905
        } else {
3906
            // SAFETY: For source type `Src` and destination type `Dst`:
3907
            // - We know that `Src: AsBytes` and `Dst: FromBytes` thanks to the
3908
            //   uses of `AssertIsAsBytes` and `AssertIsFromBytes` above.
3909
            // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
3910
            //   the use of `assert_size_eq!` above.
3911
            // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
3912
            //   the use of `assert_align_gt_eq!` above.
3913
            unsafe { $crate::macro_util::transmute_ref(e) }
3914
        }
3915
    }}
3916
}
3917
3918
/// Safely transmutes a mutable reference of one type to an mutable reference of
3919
/// another type of the same size.
3920
///
3921
/// The expression `$e` must have a concrete type, `&mut T`, where `T: Sized +
3922
/// AsBytes`. The `transmute_mut!` expression must also have a concrete type,
3923
/// `&mut U` (`U` is inferred from the calling context), where `U: Sized +
3924
/// FromBytes`. It must be the case that `align_of::<T>() >= align_of::<U>()`.
3925
///
3926
/// The lifetime of the input type, `&mut T`, must be the same as or outlive the
3927
/// lifetime of the output type, `&mut U`.
3928
///
3929
/// # Examples
3930
///
3931
/// ```
3932
/// # use zerocopy::transmute_mut;
3933
/// let mut one_dimensional: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
3934
///
3935
/// let two_dimensional: &mut [[u8; 4]; 2] = transmute_mut!(&mut one_dimensional);
3936
///
3937
/// assert_eq!(two_dimensional, &[[0, 1, 2, 3], [4, 5, 6, 7]]);
3938
///
3939
/// two_dimensional.reverse();
3940
///
3941
/// assert_eq!(one_dimensional, [4, 5, 6, 7, 0, 1, 2, 3]);
3942
/// ```
3943
///
3944
/// # Alignment increase error message
3945
///
3946
/// Because of limitations on macros, the error message generated when
3947
/// `transmute_mut!` is used to transmute from a type of lower alignment to a
3948
/// type of higher alignment is somewhat confusing. For example, the following
3949
/// code:
3950
///
3951
/// ```compile_fail
3952
/// const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
3953
/// ```
3954
///
3955
/// ...generates the following error:
3956
///
3957
/// ```text
3958
/// error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
3959
///  --> src/lib.rs:1524:34
3960
///   |
3961
/// 5 | const INCREASE_ALIGNMENT: &mut u16 = zerocopy::transmute_mut!(&mut [0u8; 2]);
3962
///   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3963
///   |
3964
///   = note: source type: `AlignOf<[u8; 2]>` (8 bits)
3965
///   = note: target type: `MaxAlignsOf<[u8; 2], u16>` (16 bits)
3966
///   = note: this error originates in the macro `$crate::assert_align_gt_eq` which comes from the expansion of the macro `transmute_mut` (in Nightly builds, run with -Z macro-backtrace for more info)
3967
/// ```
3968
///
3969
/// This is saying that `max(align_of::<T>(), align_of::<U>()) !=
3970
/// align_of::<T>()`, which is equivalent to `align_of::<T>() <
3971
/// align_of::<U>()`.
3972
#[macro_export]
3973
macro_rules! transmute_mut {
3974
    ($e:expr) => {{
3975
        // NOTE: This must be a macro (rather than a function with trait bounds)
3976
        // because there's no way, in a generic context, to enforce that two
3977
        // types have the same size or alignment.
3978
3979
        // Ensure that the source type is a mutable reference.
3980
        let e: &mut _ = $e;
3981
3982
        #[allow(unused, clippy::diverging_sub_expression)]
3983
        if false {
3984
            // This branch, though never taken, ensures that the type of `e` is
3985
            // `&mut T` where `T: 't + Sized + FromBytes + AsBytes`, that the
3986
            // type of this macro expression is `&mut U` where `U: 'u + Sized +
3987
            // FromBytes + AsBytes`.
3988
3989
            // We use immutable references here rather than mutable so that, if
3990
            // this macro is used in a const context (in which, as of this
3991
            // writing, mutable references are banned), the error message
3992
            // appears to originate in the user's code rather than in the
3993
            // internals of this macro.
3994
            struct AssertSrcIsFromBytes<'a, T: ::core::marker::Sized + $crate::FromBytes>(&'a T);
3995
            struct AssertSrcIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
3996
            struct AssertDstIsFromBytes<'a, T: ::core::marker::Sized + $crate::FromBytes>(&'a T);
3997
            struct AssertDstIsAsBytes<'a, T: ::core::marker::Sized + $crate::AsBytes>(&'a T);
3998
3999
            if true {
4000
                let _ = AssertSrcIsFromBytes(&*e);
4001
            } else {
4002
                let _ = AssertSrcIsAsBytes(&*e);
4003
            }
4004
4005
            if true {
4006
                #[allow(unused, unreachable_code)]
4007
                let u = AssertDstIsFromBytes(loop {});
4008
                &mut *u.0
4009
            } else {
4010
                #[allow(unused, unreachable_code)]
4011
                let u = AssertDstIsAsBytes(loop {});
4012
                &mut *u.0
4013
            }
4014
        } else if false {
4015
            // This branch, though never taken, ensures that `size_of::<T>() ==
4016
            // size_of::<U>()` and that that `align_of::<T>() >=
4017
            // align_of::<U>()`.
4018
4019
            // `t` is inferred to have type `T` because it's assigned to `e` (of
4020
            // type `&mut T`) as `&mut t`.
4021
            let mut t = unreachable!();
4022
            e = &mut t;
4023
4024
            // `u` is inferred to have type `U` because it's used as `&mut u` as
4025
            // the value returned from this branch.
4026
            let u;
4027
4028
            $crate::assert_size_eq!(t, u);
4029
            $crate::assert_align_gt_eq!(t, u);
4030
4031
            &mut u
4032
        } else {
4033
            // SAFETY: For source type `Src` and destination type `Dst`:
4034
            // - We know that `Src: FromBytes + AsBytes` and `Dst: FromBytes +
4035
            //   AsBytes` thanks to the uses of `AssertSrcIsFromBytes`,
4036
            //   `AssertSrcIsAsBytes`, `AssertDstIsFromBytes`, and
4037
            //   `AssertDstIsAsBytes` above.
4038
            // - We know that `size_of::<Src>() == size_of::<Dst>()` thanks to
4039
            //   the use of `assert_size_eq!` above.
4040
            // - We know that `align_of::<Src>() >= align_of::<Dst>()` thanks to
4041
            //   the use of `assert_align_gt_eq!` above.
4042
            unsafe { $crate::macro_util::transmute_mut(e) }
4043
        }
4044
    }}
4045
}
4046
4047
/// Includes a file and safely transmutes it to a value of an arbitrary type.
4048
///
4049
/// The file will be included as a byte array, `[u8; N]`, which will be
4050
/// transmuted to another type, `T`. `T` is inferred from the calling context,
4051
/// and must implement [`FromBytes`].
4052
///
4053
/// The file is located relative to the current file (similarly to how modules
4054
/// are found). The provided path is interpreted in a platform-specific way at
4055
/// compile time. So, for instance, an invocation with a Windows path containing
4056
/// backslashes `\` would not compile correctly on Unix.
4057
///
4058
/// `include_value!` is ignorant of byte order. For byte order-aware types, see
4059
/// the [`byteorder`] module.
4060
///
4061
/// # Examples
4062
///
4063
/// Assume there are two files in the same directory with the following
4064
/// contents:
4065
///
4066
/// File `data` (no trailing newline):
4067
///
4068
/// ```text
4069
/// abcd
4070
/// ```
4071
///
4072
/// File `main.rs`:
4073
///
4074
/// ```rust
4075
/// use zerocopy::include_value;
4076
/// # macro_rules! include_value {
4077
/// # ($file:expr) => { zerocopy::include_value!(concat!("../testdata/include_value/", $file)) };
4078
/// # }
4079
///
4080
/// fn main() {
4081
///     let as_u32: u32 = include_value!("data");
4082
///     assert_eq!(as_u32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));
4083
///     let as_i32: i32 = include_value!("data");
4084
///     assert_eq!(as_i32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));
4085
/// }
4086
/// ```
4087
#[doc(alias("include_bytes", "include_data", "include_type"))]
4088
#[macro_export]
4089
macro_rules! include_value {
4090
    ($file:expr $(,)?) => {
4091
        $crate::transmute!(*::core::include_bytes!($file))
4092
    };
4093
}
4094
4095
/// A typed reference derived from a byte slice.
4096
///
4097
/// A `Ref<B, T>` is a reference to a `T` which is stored in a byte slice, `B`.
4098
/// Unlike a native reference (`&T` or `&mut T`), `Ref<B, T>` has the same
4099
/// mutability as the byte slice it was constructed from (`B`).
4100
///
4101
/// # Examples
4102
///
4103
/// `Ref` can be used to treat a sequence of bytes as a structured type, and to
4104
/// read and write the fields of that type as if the byte slice reference were
4105
/// simply a reference to that type.
4106
///
4107
/// ```rust
4108
/// # #[cfg(feature = "derive")] { // This example uses derives, and won't compile without them
4109
/// use zerocopy::{AsBytes, ByteSlice, ByteSliceMut, FromBytes, FromZeroes, Ref, Unaligned};
4110
///
4111
/// #[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
4112
/// #[repr(C)]
4113
/// struct UdpHeader {
4114
///     src_port: [u8; 2],
4115
///     dst_port: [u8; 2],
4116
///     length: [u8; 2],
4117
///     checksum: [u8; 2],
4118
/// }
4119
///
4120
/// struct UdpPacket<B> {
4121
///     header: Ref<B, UdpHeader>,
4122
///     body: B,
4123
/// }
4124
///
4125
/// impl<B: ByteSlice> UdpPacket<B> {
4126
///     pub fn parse(bytes: B) -> Option<UdpPacket<B>> {
4127
///         let (header, body) = Ref::new_unaligned_from_prefix(bytes)?;
4128
///         Some(UdpPacket { header, body })
4129
///     }
4130
///
4131
///     pub fn get_src_port(&self) -> [u8; 2] {
4132
///         self.header.src_port
4133
///     }
4134
/// }
4135
///
4136
/// impl<B: ByteSliceMut> UdpPacket<B> {
4137
///     pub fn set_src_port(&mut self, src_port: [u8; 2]) {
4138
///         self.header.src_port = src_port;
4139
///     }
4140
/// }
4141
/// # }
4142
/// ```
4143
pub struct Ref<B, T: ?Sized>(B, PhantomData<T>);
4144
4145
/// Deprecated: prefer [`Ref`] instead.
4146
#[deprecated(since = "0.7.0", note = "LayoutVerified has been renamed to Ref")]
4147
#[doc(hidden)]
4148
pub type LayoutVerified<B, T> = Ref<B, T>;
4149
4150
impl<B, T> Ref<B, T>
4151
where
4152
    B: ByteSlice,
4153
{
4154
    /// Constructs a new `Ref`.
4155
    ///
4156
    /// `new` verifies that `bytes.len() == size_of::<T>()` and that `bytes` is
4157
    /// aligned to `align_of::<T>()`, and constructs a new `Ref`. If either of
4158
    /// these checks fail, it returns `None`.
4159
    #[inline]
4160
0
    pub fn new(bytes: B) -> Option<Ref<B, T>> {
4161
0
        if bytes.len() != mem::size_of::<T>() || !util::aligned_to::<_, T>(bytes.deref()) {
4162
0
            return None;
4163
0
        }
4164
0
        Some(Ref(bytes, PhantomData))
4165
0
    }
4166
4167
    /// Constructs a new `Ref` from the prefix of a byte slice.
4168
    ///
4169
    /// `new_from_prefix` verifies that `bytes.len() >= size_of::<T>()` and that
4170
    /// `bytes` is aligned to `align_of::<T>()`. It consumes the first
4171
    /// `size_of::<T>()` bytes from `bytes` to construct a `Ref`, and returns
4172
    /// the remaining bytes to the caller. If either the length or alignment
4173
    /// checks fail, it returns `None`.
4174
    #[inline]
4175
0
    pub fn new_from_prefix(bytes: B) -> Option<(Ref<B, T>, B)> {
4176
0
        if bytes.len() < mem::size_of::<T>() || !util::aligned_to::<_, T>(bytes.deref()) {
4177
0
            return None;
4178
0
        }
4179
0
        let (bytes, suffix) = bytes.split_at(mem::size_of::<T>());
4180
0
        Some((Ref(bytes, PhantomData), suffix))
4181
0
    }
4182
4183
    /// Constructs a new `Ref` from the suffix of a byte slice.
4184
    ///
4185
    /// `new_from_suffix` verifies that `bytes.len() >= size_of::<T>()` and that
4186
    /// the last `size_of::<T>()` bytes of `bytes` are aligned to
4187
    /// `align_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4188
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4189
    /// caller. If either the length or alignment checks fail, it returns
4190
    /// `None`.
4191
    #[inline]
4192
0
    pub fn new_from_suffix(bytes: B) -> Option<(B, Ref<B, T>)> {
4193
0
        let bytes_len = bytes.len();
4194
0
        let split_at = bytes_len.checked_sub(mem::size_of::<T>())?;
4195
0
        let (prefix, bytes) = bytes.split_at(split_at);
4196
0
        if !util::aligned_to::<_, T>(bytes.deref()) {
4197
0
            return None;
4198
0
        }
4199
0
        Some((prefix, Ref(bytes, PhantomData)))
4200
0
    }
4201
}
4202
4203
impl<B, T> Ref<B, [T]>
4204
where
4205
    B: ByteSlice,
4206
{
4207
    /// Constructs a new `Ref` of a slice type.
4208
    ///
4209
    /// `new_slice` verifies that `bytes.len()` is a multiple of
4210
    /// `size_of::<T>()` and that `bytes` is aligned to `align_of::<T>()`, and
4211
    /// constructs a new `Ref`. If either of these checks fail, it returns
4212
    /// `None`.
4213
    ///
4214
    /// # Panics
4215
    ///
4216
    /// `new_slice` panics if `T` is a zero-sized type.
4217
    #[inline]
4218
0
    pub fn new_slice(bytes: B) -> Option<Ref<B, [T]>> {
4219
0
        let remainder = bytes
4220
0
            .len()
4221
0
            .checked_rem(mem::size_of::<T>())
4222
0
            .expect("Ref::new_slice called on a zero-sized type");
4223
0
        if remainder != 0 || !util::aligned_to::<_, T>(bytes.deref()) {
4224
0
            return None;
4225
0
        }
4226
0
        Some(Ref(bytes, PhantomData))
4227
0
    }
4228
4229
    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice.
4230
    ///
4231
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4232
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4233
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4234
    /// and returns the remaining bytes to the caller. It also ensures that
4235
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4236
    /// length, alignment, or overflow checks fail, it returns `None`.
4237
    ///
4238
    /// # Panics
4239
    ///
4240
    /// `new_slice_from_prefix` panics if `T` is a zero-sized type.
4241
    #[inline]
4242
0
    pub fn new_slice_from_prefix(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4243
0
        let expected_len = match mem::size_of::<T>().checked_mul(count) {
4244
0
            Some(len) => len,
4245
0
            None => return None,
4246
        };
4247
0
        if bytes.len() < expected_len {
4248
0
            return None;
4249
0
        }
4250
0
        let (prefix, bytes) = bytes.split_at(expected_len);
4251
0
        Self::new_slice(prefix).map(move |l| (l, bytes))
4252
0
    }
4253
4254
    /// Constructs a new `Ref` of a slice type from the suffix of a byte slice.
4255
    ///
4256
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4257
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4258
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4259
    /// and returns the preceding bytes to the caller. It also ensures that
4260
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4261
    /// length, alignment, or overflow checks fail, it returns `None`.
4262
    ///
4263
    /// # Panics
4264
    ///
4265
    /// `new_slice_from_suffix` panics if `T` is a zero-sized type.
4266
    #[inline]
4267
0
    pub fn new_slice_from_suffix(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4268
0
        let expected_len = match mem::size_of::<T>().checked_mul(count) {
4269
0
            Some(len) => len,
4270
0
            None => return None,
4271
        };
4272
0
        let split_at = bytes.len().checked_sub(expected_len)?;
4273
0
        let (bytes, suffix) = bytes.split_at(split_at);
4274
0
        Self::new_slice(suffix).map(move |l| (bytes, l))
4275
0
    }
4276
}
4277
4278
0
fn map_zeroed<B: ByteSliceMut, T: ?Sized>(opt: Option<Ref<B, T>>) -> Option<Ref<B, T>> {
4279
0
    match opt {
4280
0
        Some(mut r) => {
4281
0
            r.0.fill(0);
4282
0
            Some(r)
4283
        }
4284
0
        None => None,
4285
    }
4286
0
}
4287
4288
0
fn map_prefix_tuple_zeroed<B: ByteSliceMut, T: ?Sized>(
4289
0
    opt: Option<(Ref<B, T>, B)>,
4290
0
) -> Option<(Ref<B, T>, B)> {
4291
0
    match opt {
4292
0
        Some((mut r, rest)) => {
4293
0
            r.0.fill(0);
4294
0
            Some((r, rest))
4295
        }
4296
0
        None => None,
4297
    }
4298
0
}
4299
4300
0
fn map_suffix_tuple_zeroed<B: ByteSliceMut, T: ?Sized>(
4301
0
    opt: Option<(B, Ref<B, T>)>,
4302
0
) -> Option<(B, Ref<B, T>)> {
4303
0
    map_prefix_tuple_zeroed(opt.map(|(a, b)| (b, a))).map(|(a, b)| (b, a))
4304
0
}
4305
4306
impl<B, T> Ref<B, T>
4307
where
4308
    B: ByteSliceMut,
4309
{
4310
    /// Constructs a new `Ref` after zeroing the bytes.
4311
    ///
4312
    /// `new_zeroed` verifies that `bytes.len() == size_of::<T>()` and that
4313
    /// `bytes` is aligned to `align_of::<T>()`, and constructs a new `Ref`. If
4314
    /// either of these checks fail, it returns `None`.
4315
    ///
4316
    /// If the checks succeed, then `bytes` will be initialized to zero. This
4317
    /// can be useful when re-using buffers to ensure that sensitive data
4318
    /// previously stored in the buffer is not leaked.
4319
    #[inline(always)]
4320
0
    pub fn new_zeroed(bytes: B) -> Option<Ref<B, T>> {
4321
0
        map_zeroed(Self::new(bytes))
4322
0
    }
4323
4324
    /// Constructs a new `Ref` from the prefix of a byte slice, zeroing the
4325
    /// prefix.
4326
    ///
4327
    /// `new_from_prefix_zeroed` verifies that `bytes.len() >= size_of::<T>()`
4328
    /// and that `bytes` is aligned to `align_of::<T>()`. It consumes the first
4329
    /// `size_of::<T>()` bytes from `bytes` to construct a `Ref`, and returns
4330
    /// the remaining bytes to the caller. If either the length or alignment
4331
    /// checks fail, it returns `None`.
4332
    ///
4333
    /// If the checks succeed, then the prefix which is consumed will be
4334
    /// initialized to zero. This can be useful when re-using buffers to ensure
4335
    /// that sensitive data previously stored in the buffer is not leaked.
4336
    #[inline(always)]
4337
0
    pub fn new_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
4338
0
        map_prefix_tuple_zeroed(Self::new_from_prefix(bytes))
4339
0
    }
4340
4341
    /// Constructs a new `Ref` from the suffix of a byte slice, zeroing the
4342
    /// suffix.
4343
    ///
4344
    /// `new_from_suffix_zeroed` verifies that `bytes.len() >= size_of::<T>()`
4345
    /// and that the last `size_of::<T>()` bytes of `bytes` are aligned to
4346
    /// `align_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4347
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4348
    /// caller. If either the length or alignment checks fail, it returns
4349
    /// `None`.
4350
    ///
4351
    /// If the checks succeed, then the suffix which is consumed will be
4352
    /// initialized to zero. This can be useful when re-using buffers to ensure
4353
    /// that sensitive data previously stored in the buffer is not leaked.
4354
    #[inline(always)]
4355
0
    pub fn new_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
4356
0
        map_suffix_tuple_zeroed(Self::new_from_suffix(bytes))
4357
0
    }
4358
}
4359
4360
impl<B, T> Ref<B, [T]>
4361
where
4362
    B: ByteSliceMut,
4363
{
4364
    /// Constructs a new `Ref` of a slice type after zeroing the bytes.
4365
    ///
4366
    /// `new_slice_zeroed` verifies that `bytes.len()` is a multiple of
4367
    /// `size_of::<T>()` and that `bytes` is aligned to `align_of::<T>()`, and
4368
    /// constructs a new `Ref`. If either of these checks fail, it returns
4369
    /// `None`.
4370
    ///
4371
    /// If the checks succeed, then `bytes` will be initialized to zero. This
4372
    /// can be useful when re-using buffers to ensure that sensitive data
4373
    /// previously stored in the buffer is not leaked.
4374
    ///
4375
    /// # Panics
4376
    ///
4377
    /// `new_slice` panics if `T` is a zero-sized type.
4378
    #[inline(always)]
4379
0
    pub fn new_slice_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
4380
0
        map_zeroed(Self::new_slice(bytes))
4381
0
    }
4382
4383
    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice,
4384
    /// after zeroing the bytes.
4385
    ///
4386
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4387
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4388
    /// first `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4389
    /// and returns the remaining bytes to the caller. It also ensures that
4390
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4391
    /// length, alignment, or overflow checks fail, it returns `None`.
4392
    ///
4393
    /// If the checks succeed, then the suffix which is consumed will be
4394
    /// initialized to zero. This can be useful when re-using buffers to ensure
4395
    /// that sensitive data previously stored in the buffer is not leaked.
4396
    ///
4397
    /// # Panics
4398
    ///
4399
    /// `new_slice_from_prefix_zeroed` panics if `T` is a zero-sized type.
4400
    #[inline(always)]
4401
0
    pub fn new_slice_from_prefix_zeroed(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4402
0
        map_prefix_tuple_zeroed(Self::new_slice_from_prefix(bytes, count))
4403
0
    }
4404
4405
    /// Constructs a new `Ref` of a slice type from the prefix of a byte slice,
4406
    /// after zeroing the bytes.
4407
    ///
4408
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4409
    /// count` and that `bytes` is aligned to `align_of::<T>()`. It consumes the
4410
    /// last `size_of::<T>() * count` bytes from `bytes` to construct a `Ref`,
4411
    /// and returns the preceding bytes to the caller. It also ensures that
4412
    /// `sizeof::<T>() * count` does not overflow a `usize`. If any of the
4413
    /// length, alignment, or overflow checks fail, it returns `None`.
4414
    ///
4415
    /// If the checks succeed, then the consumed suffix will be initialized to
4416
    /// zero. This can be useful when re-using buffers to ensure that sensitive
4417
    /// data previously stored in the buffer is not leaked.
4418
    ///
4419
    /// # Panics
4420
    ///
4421
    /// `new_slice_from_suffix_zeroed` panics if `T` is a zero-sized type.
4422
    #[inline(always)]
4423
0
    pub fn new_slice_from_suffix_zeroed(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4424
0
        map_suffix_tuple_zeroed(Self::new_slice_from_suffix(bytes, count))
4425
0
    }
4426
}
4427
4428
impl<B, T> Ref<B, T>
4429
where
4430
    B: ByteSlice,
4431
    T: Unaligned,
4432
{
4433
    /// Constructs a new `Ref` for a type with no alignment requirement.
4434
    ///
4435
    /// `new_unaligned` verifies that `bytes.len() == size_of::<T>()` and
4436
    /// constructs a new `Ref`. If the check fails, it returns `None`.
4437
    #[inline(always)]
4438
0
    pub fn new_unaligned(bytes: B) -> Option<Ref<B, T>> {
4439
0
        Ref::new(bytes)
4440
0
    }
4441
4442
    /// Constructs a new `Ref` from the prefix of a byte slice for a type with
4443
    /// no alignment requirement.
4444
    ///
4445
    /// `new_unaligned_from_prefix` verifies that `bytes.len() >=
4446
    /// size_of::<T>()`. It consumes the first `size_of::<T>()` bytes from
4447
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4448
    /// caller. If the length check fails, it returns `None`.
4449
    #[inline(always)]
4450
0
    pub fn new_unaligned_from_prefix(bytes: B) -> Option<(Ref<B, T>, B)> {
4451
0
        Ref::new_from_prefix(bytes)
4452
0
    }
4453
4454
    /// Constructs a new `Ref` from the suffix of a byte slice for a type with
4455
    /// no alignment requirement.
4456
    ///
4457
    /// `new_unaligned_from_suffix` verifies that `bytes.len() >=
4458
    /// size_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4459
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4460
    /// caller. If the length check fails, it returns `None`.
4461
    #[inline(always)]
4462
0
    pub fn new_unaligned_from_suffix(bytes: B) -> Option<(B, Ref<B, T>)> {
4463
0
        Ref::new_from_suffix(bytes)
4464
0
    }
4465
}
4466
4467
impl<B, T> Ref<B, [T]>
4468
where
4469
    B: ByteSlice,
4470
    T: Unaligned,
4471
{
4472
    /// Constructs a new `Ref` of a slice type with no alignment requirement.
4473
    ///
4474
    /// `new_slice_unaligned` verifies that `bytes.len()` is a multiple of
4475
    /// `size_of::<T>()` and constructs a new `Ref`. If the check fails, it
4476
    /// returns `None`.
4477
    ///
4478
    /// # Panics
4479
    ///
4480
    /// `new_slice` panics if `T` is a zero-sized type.
4481
    #[inline(always)]
4482
0
    pub fn new_slice_unaligned(bytes: B) -> Option<Ref<B, [T]>> {
4483
0
        Ref::new_slice(bytes)
4484
0
    }
4485
4486
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4487
    /// from the prefix of a byte slice.
4488
    ///
4489
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4490
    /// count`. It consumes the first `size_of::<T>() * count` bytes from
4491
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4492
    /// caller. It also ensures that `sizeof::<T>() * count` does not overflow a
4493
    /// `usize`. If either the length, or overflow checks fail, it returns
4494
    /// `None`.
4495
    ///
4496
    /// # Panics
4497
    ///
4498
    /// `new_slice_unaligned_from_prefix` panics if `T` is a zero-sized type.
4499
    #[inline(always)]
4500
0
    pub fn new_slice_unaligned_from_prefix(bytes: B, count: usize) -> Option<(Ref<B, [T]>, B)> {
4501
0
        Ref::new_slice_from_prefix(bytes, count)
4502
0
    }
4503
4504
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4505
    /// from the suffix of a byte slice.
4506
    ///
4507
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4508
    /// count`. It consumes the last `size_of::<T>() * count` bytes from `bytes`
4509
    /// to construct a `Ref`, and returns the remaining bytes to the caller. It
4510
    /// also ensures that `sizeof::<T>() * count` does not overflow a `usize`.
4511
    /// If either the length, or overflow checks fail, it returns `None`.
4512
    ///
4513
    /// # Panics
4514
    ///
4515
    /// `new_slice_unaligned_from_suffix` panics if `T` is a zero-sized type.
4516
    #[inline(always)]
4517
0
    pub fn new_slice_unaligned_from_suffix(bytes: B, count: usize) -> Option<(B, Ref<B, [T]>)> {
4518
0
        Ref::new_slice_from_suffix(bytes, count)
4519
0
    }
4520
}
4521
4522
impl<B, T> Ref<B, T>
4523
where
4524
    B: ByteSliceMut,
4525
    T: Unaligned,
4526
{
4527
    /// Constructs a new `Ref` for a type with no alignment requirement, zeroing
4528
    /// the bytes.
4529
    ///
4530
    /// `new_unaligned_zeroed` verifies that `bytes.len() == size_of::<T>()` and
4531
    /// constructs a new `Ref`. If the check fails, it returns `None`.
4532
    ///
4533
    /// If the check succeeds, then `bytes` will be initialized to zero. This
4534
    /// can be useful when re-using buffers to ensure that sensitive data
4535
    /// previously stored in the buffer is not leaked.
4536
    #[inline(always)]
4537
0
    pub fn new_unaligned_zeroed(bytes: B) -> Option<Ref<B, T>> {
4538
0
        map_zeroed(Self::new_unaligned(bytes))
4539
0
    }
4540
4541
    /// Constructs a new `Ref` from the prefix of a byte slice for a type with
4542
    /// no alignment requirement, zeroing the prefix.
4543
    ///
4544
    /// `new_unaligned_from_prefix_zeroed` verifies that `bytes.len() >=
4545
    /// size_of::<T>()`. It consumes the first `size_of::<T>()` bytes from
4546
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4547
    /// caller. If the length check fails, it returns `None`.
4548
    ///
4549
    /// If the check succeeds, then the prefix which is consumed will be
4550
    /// initialized to zero. This can be useful when re-using buffers to ensure
4551
    /// that sensitive data previously stored in the buffer is not leaked.
4552
    #[inline(always)]
4553
0
    pub fn new_unaligned_from_prefix_zeroed(bytes: B) -> Option<(Ref<B, T>, B)> {
4554
0
        map_prefix_tuple_zeroed(Self::new_unaligned_from_prefix(bytes))
4555
0
    }
4556
4557
    /// Constructs a new `Ref` from the suffix of a byte slice for a type with
4558
    /// no alignment requirement, zeroing the suffix.
4559
    ///
4560
    /// `new_unaligned_from_suffix_zeroed` verifies that `bytes.len() >=
4561
    /// size_of::<T>()`. It consumes the last `size_of::<T>()` bytes from
4562
    /// `bytes` to construct a `Ref`, and returns the preceding bytes to the
4563
    /// caller. If the length check fails, it returns `None`.
4564
    ///
4565
    /// If the check succeeds, then the suffix which is consumed will be
4566
    /// initialized to zero. This can be useful when re-using buffers to ensure
4567
    /// that sensitive data previously stored in the buffer is not leaked.
4568
    #[inline(always)]
4569
0
    pub fn new_unaligned_from_suffix_zeroed(bytes: B) -> Option<(B, Ref<B, T>)> {
4570
0
        map_suffix_tuple_zeroed(Self::new_unaligned_from_suffix(bytes))
4571
0
    }
4572
}
4573
4574
impl<B, T> Ref<B, [T]>
4575
where
4576
    B: ByteSliceMut,
4577
    T: Unaligned,
4578
{
4579
    /// Constructs a new `Ref` for a slice type with no alignment requirement,
4580
    /// zeroing the bytes.
4581
    ///
4582
    /// `new_slice_unaligned_zeroed` verifies that `bytes.len()` is a multiple
4583
    /// of `size_of::<T>()` and constructs a new `Ref`. If the check fails, it
4584
    /// returns `None`.
4585
    ///
4586
    /// If the check succeeds, then `bytes` will be initialized to zero. This
4587
    /// can be useful when re-using buffers to ensure that sensitive data
4588
    /// previously stored in the buffer is not leaked.
4589
    ///
4590
    /// # Panics
4591
    ///
4592
    /// `new_slice` panics if `T` is a zero-sized type.
4593
    #[inline(always)]
4594
0
    pub fn new_slice_unaligned_zeroed(bytes: B) -> Option<Ref<B, [T]>> {
4595
0
        map_zeroed(Self::new_slice_unaligned(bytes))
4596
0
    }
4597
4598
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4599
    /// from the prefix of a byte slice, after zeroing the bytes.
4600
    ///
4601
    /// `new_slice_from_prefix` verifies that `bytes.len() >= size_of::<T>() *
4602
    /// count`. It consumes the first `size_of::<T>() * count` bytes from
4603
    /// `bytes` to construct a `Ref`, and returns the remaining bytes to the
4604
    /// caller. It also ensures that `sizeof::<T>() * count` does not overflow a
4605
    /// `usize`. If either the length, or overflow checks fail, it returns
4606
    /// `None`.
4607
    ///
4608
    /// If the checks succeed, then the prefix will be initialized to zero. This
4609
    /// can be useful when re-using buffers to ensure that sensitive data
4610
    /// previously stored in the buffer is not leaked.
4611
    ///
4612
    /// # Panics
4613
    ///
4614
    /// `new_slice_unaligned_from_prefix_zeroed` panics if `T` is a zero-sized
4615
    /// type.
4616
    #[inline(always)]
4617
0
    pub fn new_slice_unaligned_from_prefix_zeroed(
4618
0
        bytes: B,
4619
0
        count: usize,
4620
0
    ) -> Option<(Ref<B, [T]>, B)> {
4621
0
        map_prefix_tuple_zeroed(Self::new_slice_unaligned_from_prefix(bytes, count))
4622
0
    }
4623
4624
    /// Constructs a new `Ref` of a slice type with no alignment requirement
4625
    /// from the suffix of a byte slice, after zeroing the bytes.
4626
    ///
4627
    /// `new_slice_from_suffix` verifies that `bytes.len() >= size_of::<T>() *
4628
    /// count`. It consumes the last `size_of::<T>() * count` bytes from `bytes`
4629
    /// to construct a `Ref`, and returns the remaining bytes to the caller. It
4630
    /// also ensures that `sizeof::<T>() * count` does not overflow a `usize`.
4631
    /// If either the length, or overflow checks fail, it returns `None`.
4632
    ///
4633
    /// If the checks succeed, then the suffix will be initialized to zero. This
4634
    /// can be useful when re-using buffers to ensure that sensitive data
4635
    /// previously stored in the buffer is not leaked.
4636
    ///
4637
    /// # Panics
4638
    ///
4639
    /// `new_slice_unaligned_from_suffix_zeroed` panics if `T` is a zero-sized
4640
    /// type.
4641
    #[inline(always)]
4642
0
    pub fn new_slice_unaligned_from_suffix_zeroed(
4643
0
        bytes: B,
4644
0
        count: usize,
4645
0
    ) -> Option<(B, Ref<B, [T]>)> {
4646
0
        map_suffix_tuple_zeroed(Self::new_slice_unaligned_from_suffix(bytes, count))
4647
0
    }
4648
}
4649
4650
impl<'a, B, T> Ref<B, T>
4651
where
4652
    B: 'a + ByteSlice,
4653
    T: FromBytes,
4654
{
4655
    /// Converts this `Ref` into a reference.
4656
    ///
4657
    /// `into_ref` consumes the `Ref`, and returns a reference to `T`.
4658
    #[inline(always)]
4659
0
    pub fn into_ref(self) -> &'a T {
4660
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4661
4662
        // SAFETY: According to the safety preconditions on
4663
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4664
        // ensures that, given `B: 'a`, it is sound to drop `self` and still
4665
        // access the underlying memory using reads for `'a`.
4666
0
        unsafe { self.deref_helper() }
4667
0
    }
4668
}
4669
4670
impl<'a, B, T> Ref<B, T>
4671
where
4672
    B: 'a + ByteSliceMut,
4673
    T: FromBytes + AsBytes,
4674
{
4675
    /// Converts this `Ref` into a mutable reference.
4676
    ///
4677
    /// `into_mut` consumes the `Ref`, and returns a mutable reference to `T`.
4678
    #[inline(always)]
4679
0
    pub fn into_mut(mut self) -> &'a mut T {
4680
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4681
4682
        // SAFETY: According to the safety preconditions on
4683
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4684
        // ensures that, given `B: 'a + ByteSliceMut`, it is sound to drop
4685
        // `self` and still access the underlying memory using both reads and
4686
        // writes for `'a`.
4687
0
        unsafe { self.deref_mut_helper() }
4688
0
    }
4689
}
4690
4691
impl<'a, B, T> Ref<B, [T]>
4692
where
4693
    B: 'a + ByteSlice,
4694
    T: FromBytes,
4695
{
4696
    /// Converts this `Ref` into a slice reference.
4697
    ///
4698
    /// `into_slice` consumes the `Ref`, and returns a reference to `[T]`.
4699
    #[inline(always)]
4700
0
    pub fn into_slice(self) -> &'a [T] {
4701
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4702
4703
        // SAFETY: According to the safety preconditions on
4704
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4705
        // ensures that, given `B: 'a`, it is sound to drop `self` and still
4706
        // access the underlying memory using reads for `'a`.
4707
0
        unsafe { self.deref_slice_helper() }
4708
0
    }
4709
}
4710
4711
impl<'a, B, T> Ref<B, [T]>
4712
where
4713
    B: 'a + ByteSliceMut,
4714
    T: FromBytes + AsBytes,
4715
{
4716
    /// Converts this `Ref` into a mutable slice reference.
4717
    ///
4718
    /// `into_mut_slice` consumes the `Ref`, and returns a mutable reference to
4719
    /// `[T]`.
4720
    #[inline(always)]
4721
0
    pub fn into_mut_slice(mut self) -> &'a mut [T] {
4722
0
        assert!(B::INTO_REF_INTO_MUT_ARE_SOUND);
4723
4724
        // SAFETY: According to the safety preconditions on
4725
        // `ByteSlice::INTO_REF_INTO_MUT_ARE_SOUND`, the preceding assert
4726
        // ensures that, given `B: 'a + ByteSliceMut`, it is sound to drop
4727
        // `self` and still access the underlying memory using both reads and
4728
        // writes for `'a`.
4729
0
        unsafe { self.deref_mut_slice_helper() }
4730
0
    }
4731
}
4732
4733
impl<B, T> Ref<B, T>
4734
where
4735
    B: ByteSlice,
4736
    T: FromBytes,
4737
{
4738
    /// Creates an immutable reference to `T` with a specific lifetime.
4739
    ///
4740
    /// # Safety
4741
    ///
4742
    /// The type bounds on this method guarantee that it is safe to create an
4743
    /// immutable reference to `T` from `self`. However, since the lifetime `'a`
4744
    /// is not required to be shorter than the lifetime of the reference to
4745
    /// `self`, the caller must guarantee that the lifetime `'a` is valid for
4746
    /// this reference. In particular, the referent must exist for all of `'a`,
4747
    /// and no mutable references to the same memory may be constructed during
4748
    /// `'a`.
4749
0
    unsafe fn deref_helper<'a>(&self) -> &'a T {
4750
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4751
        #[allow(clippy::undocumented_unsafe_blocks)]
4752
        unsafe {
4753
0
            &*self.0.as_ptr().cast::<T>()
4754
        }
4755
0
    }
4756
}
4757
4758
impl<B, T> Ref<B, T>
4759
where
4760
    B: ByteSliceMut,
4761
    T: FromBytes + AsBytes,
4762
{
4763
    /// Creates a mutable reference to `T` with a specific lifetime.
4764
    ///
4765
    /// # Safety
4766
    ///
4767
    /// The type bounds on this method guarantee that it is safe to create a
4768
    /// mutable reference to `T` from `self`. However, since the lifetime `'a`
4769
    /// is not required to be shorter than the lifetime of the reference to
4770
    /// `self`, the caller must guarantee that the lifetime `'a` is valid for
4771
    /// this reference. In particular, the referent must exist for all of `'a`,
4772
    /// and no other references - mutable or immutable - to the same memory may
4773
    /// be constructed during `'a`.
4774
0
    unsafe fn deref_mut_helper<'a>(&mut self) -> &'a mut T {
4775
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4776
        #[allow(clippy::undocumented_unsafe_blocks)]
4777
0
        unsafe {
4778
0
            &mut *self.0.as_mut_ptr().cast::<T>()
4779
0
        }
4780
0
    }
4781
}
4782
4783
impl<B, T> Ref<B, [T]>
4784
where
4785
    B: ByteSlice,
4786
    T: FromBytes,
4787
{
4788
    /// Creates an immutable reference to `[T]` with a specific lifetime.
4789
    ///
4790
    /// # Safety
4791
    ///
4792
    /// `deref_slice_helper` has the same safety requirements as `deref_helper`.
4793
0
    unsafe fn deref_slice_helper<'a>(&self) -> &'a [T] {
4794
0
        let len = self.0.len();
4795
0
        let elem_size = mem::size_of::<T>();
4796
0
        debug_assert_ne!(elem_size, 0);
4797
        // `Ref<_, [T]>` maintains the invariant that `size_of::<T>() > 0`.
4798
        // Thus, neither the mod nor division operations here can panic.
4799
        #[allow(clippy::arithmetic_side_effects)]
4800
0
        let elems = {
4801
0
            debug_assert_eq!(len % elem_size, 0);
4802
0
            len / elem_size
4803
        };
4804
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4805
        #[allow(clippy::undocumented_unsafe_blocks)]
4806
        unsafe {
4807
0
            slice::from_raw_parts(self.0.as_ptr().cast::<T>(), elems)
4808
        }
4809
0
    }
4810
}
4811
4812
impl<B, T> Ref<B, [T]>
4813
where
4814
    B: ByteSliceMut,
4815
    T: FromBytes + AsBytes,
4816
{
4817
    /// Creates a mutable reference to `[T]` with a specific lifetime.
4818
    ///
4819
    /// # Safety
4820
    ///
4821
    /// `deref_mut_slice_helper` has the same safety requirements as
4822
    /// `deref_mut_helper`.
4823
0
    unsafe fn deref_mut_slice_helper<'a>(&mut self) -> &'a mut [T] {
4824
0
        let len = self.0.len();
4825
0
        let elem_size = mem::size_of::<T>();
4826
0
        debug_assert_ne!(elem_size, 0);
4827
        // `Ref<_, [T]>` maintains the invariant that `size_of::<T>() > 0`.
4828
        // Thus, neither the mod nor division operations here can panic.
4829
        #[allow(clippy::arithmetic_side_effects)]
4830
0
        let elems = {
4831
0
            debug_assert_eq!(len % elem_size, 0);
4832
0
            len / elem_size
4833
        };
4834
        // TODO(#429): Add a "SAFETY" comment and remove this `allow`.
4835
        #[allow(clippy::undocumented_unsafe_blocks)]
4836
0
        unsafe {
4837
0
            slice::from_raw_parts_mut(self.0.as_mut_ptr().cast::<T>(), elems)
4838
0
        }
4839
0
    }
4840
}
4841
4842
impl<B, T> Ref<B, T>
4843
where
4844
    B: ByteSlice,
4845
    T: ?Sized,
4846
{
4847
    /// Gets the underlying bytes.
4848
    #[inline]
4849
0
    pub fn bytes(&self) -> &[u8] {
4850
0
        &self.0
4851
0
    }
4852
}
4853
4854
impl<B, T> Ref<B, T>
4855
where
4856
    B: ByteSliceMut,
4857
    T: ?Sized,
4858
{
4859
    /// Gets the underlying bytes mutably.
4860
    #[inline]
4861
0
    pub fn bytes_mut(&mut self) -> &mut [u8] {
4862
0
        &mut self.0
4863
0
    }
4864
}
4865
4866
impl<B, T> Ref<B, T>
4867
where
4868
    B: ByteSlice,
4869
    T: FromBytes,
4870
{
4871
    /// Reads a copy of `T`.
4872
    #[inline]
4873
0
    pub fn read(&self) -> T {
4874
        // SAFETY: Because of the invariants on `Ref`, we know that `self.0` is
4875
        // at least `size_of::<T>()` bytes long, and that it is at least as
4876
        // aligned as `align_of::<T>()`. Because `T: FromBytes`, it is sound to
4877
        // interpret these bytes as a `T`.
4878
0
        unsafe { ptr::read(self.0.as_ptr().cast::<T>()) }
4879
0
    }
4880
}
4881
4882
impl<B, T> Ref<B, T>
4883
where
4884
    B: ByteSliceMut,
4885
    T: AsBytes,
4886
{
4887
    /// Writes the bytes of `t` and then forgets `t`.
4888
    #[inline]
4889
0
    pub fn write(&mut self, t: T) {
4890
        // SAFETY: Because of the invariants on `Ref`, we know that `self.0` is
4891
        // at least `size_of::<T>()` bytes long, and that it is at least as
4892
        // aligned as `align_of::<T>()`. Writing `t` to the buffer will allow
4893
        // all of the bytes of `t` to be accessed as a `[u8]`, but because `T:
4894
        // AsBytes`, we know this is sound.
4895
0
        unsafe { ptr::write(self.0.as_mut_ptr().cast::<T>(), t) }
4896
0
    }
4897
}
4898
4899
impl<B, T> Deref for Ref<B, T>
4900
where
4901
    B: ByteSlice,
4902
    T: FromBytes,
4903
{
4904
    type Target = T;
4905
    #[inline]
4906
0
    fn deref(&self) -> &T {
4907
        // SAFETY: This is sound because the lifetime of `self` is the same as
4908
        // the lifetime of the return value, meaning that a) the returned
4909
        // reference cannot outlive `self` and, b) no mutable methods on `self`
4910
        // can be called during the lifetime of the returned reference. See the
4911
        // documentation on `deref_helper` for what invariants we are required
4912
        // to uphold.
4913
0
        unsafe { self.deref_helper() }
4914
0
    }
4915
}
4916
4917
impl<B, T> DerefMut for Ref<B, T>
4918
where
4919
    B: ByteSliceMut,
4920
    T: FromBytes + AsBytes,
4921
{
4922
    #[inline]
4923
0
    fn deref_mut(&mut self) -> &mut T {
4924
        // SAFETY: This is sound because the lifetime of `self` is the same as
4925
        // the lifetime of the return value, meaning that a) the returned
4926
        // reference cannot outlive `self` and, b) no other methods on `self`
4927
        // can be called during the lifetime of the returned reference. See the
4928
        // documentation on `deref_mut_helper` for what invariants we are
4929
        // required to uphold.
4930
0
        unsafe { self.deref_mut_helper() }
4931
0
    }
4932
}
4933
4934
impl<B, T> Deref for Ref<B, [T]>
4935
where
4936
    B: ByteSlice,
4937
    T: FromBytes,
4938
{
4939
    type Target = [T];
4940
    #[inline]
4941
0
    fn deref(&self) -> &[T] {
4942
        // SAFETY: This is sound because the lifetime of `self` is the same as
4943
        // the lifetime of the return value, meaning that a) the returned
4944
        // reference cannot outlive `self` and, b) no mutable methods on `self`
4945
        // can be called during the lifetime of the returned reference. See the
4946
        // documentation on `deref_slice_helper` for what invariants we are
4947
        // required to uphold.
4948
0
        unsafe { self.deref_slice_helper() }
4949
0
    }
4950
}
4951
4952
impl<B, T> DerefMut for Ref<B, [T]>
4953
where
4954
    B: ByteSliceMut,
4955
    T: FromBytes + AsBytes,
4956
{
4957
    #[inline]
4958
0
    fn deref_mut(&mut self) -> &mut [T] {
4959
        // SAFETY: This is sound because the lifetime of `self` is the same as
4960
        // the lifetime of the return value, meaning that a) the returned
4961
        // reference cannot outlive `self` and, b) no other methods on `self`
4962
        // can be called during the lifetime of the returned reference. See the
4963
        // documentation on `deref_mut_slice_helper` for what invariants we are
4964
        // required to uphold.
4965
0
        unsafe { self.deref_mut_slice_helper() }
4966
0
    }
4967
}
4968
4969
impl<T, B> Display for Ref<B, T>
4970
where
4971
    B: ByteSlice,
4972
    T: FromBytes + Display,
4973
{
4974
    #[inline]
4975
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
4976
0
        let inner: &T = self;
4977
0
        inner.fmt(fmt)
4978
0
    }
4979
}
4980
4981
impl<T, B> Display for Ref<B, [T]>
4982
where
4983
    B: ByteSlice,
4984
    T: FromBytes,
4985
    [T]: Display,
4986
{
4987
    #[inline]
4988
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
4989
0
        let inner: &[T] = self;
4990
0
        inner.fmt(fmt)
4991
0
    }
4992
}
4993
4994
impl<T, B> Debug for Ref<B, T>
4995
where
4996
    B: ByteSlice,
4997
    T: FromBytes + Debug,
4998
{
4999
    #[inline]
5000
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
5001
0
        let inner: &T = self;
5002
0
        fmt.debug_tuple("Ref").field(&inner).finish()
5003
0
    }
5004
}
5005
5006
impl<T, B> Debug for Ref<B, [T]>
5007
where
5008
    B: ByteSlice,
5009
    T: FromBytes + Debug,
5010
{
5011
    #[inline]
5012
0
    fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
5013
0
        let inner: &[T] = self;
5014
0
        fmt.debug_tuple("Ref").field(&inner).finish()
5015
0
    }
5016
}
5017
5018
impl<T, B> Eq for Ref<B, T>
5019
where
5020
    B: ByteSlice,
5021
    T: FromBytes + Eq,
5022
{
5023
}
5024
5025
impl<T, B> Eq for Ref<B, [T]>
5026
where
5027
    B: ByteSlice,
5028
    T: FromBytes + Eq,
5029
{
5030
}
5031
5032
impl<T, B> PartialEq for Ref<B, T>
5033
where
5034
    B: ByteSlice,
5035
    T: FromBytes + PartialEq,
5036
{
5037
    #[inline]
5038
0
    fn eq(&self, other: &Self) -> bool {
5039
0
        self.deref().eq(other.deref())
5040
0
    }
5041
}
5042
5043
impl<T, B> PartialEq for Ref<B, [T]>
5044
where
5045
    B: ByteSlice,
5046
    T: FromBytes + PartialEq,
5047
{
5048
    #[inline]
5049
0
    fn eq(&self, other: &Self) -> bool {
5050
0
        self.deref().eq(other.deref())
5051
0
    }
5052
}
5053
5054
impl<T, B> Ord for Ref<B, T>
5055
where
5056
    B: ByteSlice,
5057
    T: FromBytes + Ord,
5058
{
5059
    #[inline]
5060
0
    fn cmp(&self, other: &Self) -> Ordering {
5061
0
        let inner: &T = self;
5062
0
        let other_inner: &T = other;
5063
0
        inner.cmp(other_inner)
5064
0
    }
5065
}
5066
5067
impl<T, B> Ord for Ref<B, [T]>
5068
where
5069
    B: ByteSlice,
5070
    T: FromBytes + Ord,
5071
{
5072
    #[inline]
5073
0
    fn cmp(&self, other: &Self) -> Ordering {
5074
0
        let inner: &[T] = self;
5075
0
        let other_inner: &[T] = other;
5076
0
        inner.cmp(other_inner)
5077
0
    }
5078
}
5079
5080
impl<T, B> PartialOrd for Ref<B, T>
5081
where
5082
    B: ByteSlice,
5083
    T: FromBytes + PartialOrd,
5084
{
5085
    #[inline]
5086
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
5087
0
        let inner: &T = self;
5088
0
        let other_inner: &T = other;
5089
0
        inner.partial_cmp(other_inner)
5090
0
    }
5091
}
5092
5093
impl<T, B> PartialOrd for Ref<B, [T]>
5094
where
5095
    B: ByteSlice,
5096
    T: FromBytes + PartialOrd,
5097
{
5098
    #[inline]
5099
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
5100
0
        let inner: &[T] = self;
5101
0
        let other_inner: &[T] = other;
5102
0
        inner.partial_cmp(other_inner)
5103
0
    }
5104
}
5105
5106
mod sealed {
5107
    pub trait ByteSliceSealed {}
5108
}
5109
5110
// ByteSlice and ByteSliceMut abstract over [u8] references (&[u8], &mut [u8],
5111
// Ref<[u8]>, RefMut<[u8]>, etc). We rely on various behaviors of these
5112
// references such as that a given reference will never changes its length
5113
// between calls to deref() or deref_mut(), and that split_at() works as
5114
// expected. If ByteSlice or ByteSliceMut were not sealed, consumers could
5115
// implement them in a way that violated these behaviors, and would break our
5116
// unsafe code. Thus, we seal them and implement it only for known-good
5117
// reference types. For the same reason, they're unsafe traits.
5118
5119
#[allow(clippy::missing_safety_doc)] // TODO(fxbug.dev/99068)
5120
/// A mutable or immutable reference to a byte slice.
5121
///
5122
/// `ByteSlice` abstracts over the mutability of a byte slice reference, and is
5123
/// implemented for various special reference types such as `Ref<[u8]>` and
5124
/// `RefMut<[u8]>`.
5125
///
5126
/// Note that, while it would be technically possible, `ByteSlice` is not
5127
/// implemented for [`Vec<u8>`], as the only way to implement the [`split_at`]
5128
/// method would involve reallocation, and `split_at` must be a very cheap
5129
/// operation in order for the utilities in this crate to perform as designed.
5130
///
5131
/// [`split_at`]: crate::ByteSlice::split_at
5132
// It may seem overkill to go to this length to ensure that this doc link never
5133
// breaks. We do this because it simplifies CI - it means that generating docs
5134
// always succeeds, so we don't need special logic to only generate docs under
5135
// certain features.
5136
#[cfg_attr(feature = "alloc", doc = "[`Vec<u8>`]: alloc::vec::Vec")]
5137
#[cfg_attr(
5138
    not(feature = "alloc"),
5139
    doc = "[`Vec<u8>`]: https://doc.rust-lang.org/std/vec/struct.Vec.html"
5140
)]
5141
pub unsafe trait ByteSlice: Deref<Target = [u8]> + Sized + sealed::ByteSliceSealed {
5142
    /// Are the [`Ref::into_ref`] and [`Ref::into_mut`] methods sound when used
5143
    /// with `Self`? If not, evaluating this constant must panic at compile
5144
    /// time.
5145
    ///
5146
    /// This exists to work around #716 on versions of zerocopy prior to 0.8.
5147
    ///
5148
    /// # Safety
5149
    ///
5150
    /// This may only be set to true if the following holds: Given the
5151
    /// following:
5152
    /// - `Self: 'a`
5153
    /// - `bytes: Self`
5154
    /// - `let ptr = bytes.as_ptr()`
5155
    ///
5156
    /// ...then:
5157
    /// - Using `ptr` to read the memory previously addressed by `bytes` is
5158
    ///   sound for `'a` even after `bytes` has been dropped.
5159
    /// - If `Self: ByteSliceMut`, using `ptr` to write the memory previously
5160
    ///   addressed by `bytes` is sound for `'a` even after `bytes` has been
5161
    ///   dropped.
5162
    #[doc(hidden)]
5163
    const INTO_REF_INTO_MUT_ARE_SOUND: bool;
5164
5165
    /// Gets a raw pointer to the first byte in the slice.
5166
    #[inline]
5167
0
    fn as_ptr(&self) -> *const u8 {
5168
0
        <[u8]>::as_ptr(self)
5169
0
    }
5170
5171
    /// Splits the slice at the midpoint.
5172
    ///
5173
    /// `x.split_at(mid)` returns `x[..mid]` and `x[mid..]`.
5174
    ///
5175
    /// # Panics
5176
    ///
5177
    /// `x.split_at(mid)` panics if `mid > x.len()`.
5178
    fn split_at(self, mid: usize) -> (Self, Self);
5179
}
5180
5181
#[allow(clippy::missing_safety_doc)] // TODO(fxbug.dev/99068)
5182
/// A mutable reference to a byte slice.
5183
///
5184
/// `ByteSliceMut` abstracts over various ways of storing a mutable reference to
5185
/// a byte slice, and is implemented for various special reference types such as
5186
/// `RefMut<[u8]>`.
5187
pub unsafe trait ByteSliceMut: ByteSlice + DerefMut {
5188
    /// Gets a mutable raw pointer to the first byte in the slice.
5189
    #[inline]
5190
0
    fn as_mut_ptr(&mut self) -> *mut u8 {
5191
0
        <[u8]>::as_mut_ptr(self)
5192
0
    }
5193
}
5194
5195
impl<'a> sealed::ByteSliceSealed for &'a [u8] {}
5196
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5197
#[allow(clippy::undocumented_unsafe_blocks)]
5198
unsafe impl<'a> ByteSlice for &'a [u8] {
5199
    // SAFETY: If `&'b [u8]: 'a`, then the underlying memory is treated as
5200
    // borrowed immutably for `'a` even if the slice itself is dropped.
5201
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = true;
5202
5203
    #[inline]
5204
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5205
0
        <[u8]>::split_at(self, mid)
5206
0
    }
5207
}
5208
5209
impl<'a> sealed::ByteSliceSealed for &'a mut [u8] {}
5210
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5211
#[allow(clippy::undocumented_unsafe_blocks)]
5212
unsafe impl<'a> ByteSlice for &'a mut [u8] {
5213
    // SAFETY: If `&'b mut [u8]: 'a`, then the underlying memory is treated as
5214
    // borrowed mutably for `'a` even if the slice itself is dropped.
5215
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = true;
5216
5217
    #[inline]
5218
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5219
0
        <[u8]>::split_at_mut(self, mid)
5220
0
    }
5221
}
5222
5223
impl<'a> sealed::ByteSliceSealed for cell::Ref<'a, [u8]> {}
5224
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5225
#[allow(clippy::undocumented_unsafe_blocks)]
5226
unsafe impl<'a> ByteSlice for cell::Ref<'a, [u8]> {
5227
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = if !cfg!(doc) {
5228
        panic!("Ref::into_ref and Ref::into_mut are unsound when used with core::cell::Ref; see https://github.com/google/zerocopy/issues/716")
5229
    } else {
5230
        // When compiling documentation, allow the evaluation of this constant
5231
        // to succeed. This doesn't represent a soundness hole - it just delays
5232
        // any error to runtime. The reason we need this is that, otherwise,
5233
        // `rustdoc` will fail when trying to document this item.
5234
        false
5235
    };
5236
5237
    #[inline]
5238
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5239
0
        cell::Ref::map_split(self, |slice| <[u8]>::split_at(slice, mid))
5240
0
    }
5241
}
5242
5243
impl<'a> sealed::ByteSliceSealed for RefMut<'a, [u8]> {}
5244
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5245
#[allow(clippy::undocumented_unsafe_blocks)]
5246
unsafe impl<'a> ByteSlice for RefMut<'a, [u8]> {
5247
    const INTO_REF_INTO_MUT_ARE_SOUND: bool = if !cfg!(doc) {
5248
        panic!("Ref::into_ref and Ref::into_mut are unsound when used with core::cell::RefMut; see https://github.com/google/zerocopy/issues/716")
5249
    } else {
5250
        // When compiling documentation, allow the evaluation of this constant
5251
        // to succeed. This doesn't represent a soundness hole - it just delays
5252
        // any error to runtime. The reason we need this is that, otherwise,
5253
        // `rustdoc` will fail when trying to document this item.
5254
        false
5255
    };
5256
5257
    #[inline]
5258
0
    fn split_at(self, mid: usize) -> (Self, Self) {
5259
0
        RefMut::map_split(self, |slice| <[u8]>::split_at_mut(slice, mid))
5260
0
    }
5261
}
5262
5263
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5264
#[allow(clippy::undocumented_unsafe_blocks)]
5265
unsafe impl<'a> ByteSliceMut for &'a mut [u8] {}
5266
5267
// TODO(#429): Add a "SAFETY" comment and remove this `allow`.
5268
#[allow(clippy::undocumented_unsafe_blocks)]
5269
unsafe impl<'a> ByteSliceMut for RefMut<'a, [u8]> {}
5270
5271
#[cfg(feature = "alloc")]
5272
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
5273
mod alloc_support {
5274
    use alloc::vec::Vec;
5275
5276
    use super::*;
5277
5278
    /// Extends a `Vec<T>` by pushing `additional` new items onto the end of the
5279
    /// vector. The new items are initialized with zeroes.
5280
    ///
5281
    /// # Panics
5282
    ///
5283
    /// Panics if `Vec::reserve(additional)` fails to reserve enough memory.
5284
    #[inline(always)]
5285
    pub fn extend_vec_zeroed<T: FromZeroes>(v: &mut Vec<T>, additional: usize) {
5286
        insert_vec_zeroed(v, v.len(), additional);
5287
    }
5288
5289
    /// Inserts `additional` new items into `Vec<T>` at `position`.
5290
    /// The new items are initialized with zeroes.
5291
    ///
5292
    /// # Panics
5293
    ///
5294
    /// * Panics if `position > v.len()`.
5295
    /// * Panics if `Vec::reserve(additional)` fails to reserve enough memory.
5296
    #[inline]
5297
    pub fn insert_vec_zeroed<T: FromZeroes>(v: &mut Vec<T>, position: usize, additional: usize) {
5298
        assert!(position <= v.len());
5299
        v.reserve(additional);
5300
        // SAFETY: The `reserve` call guarantees that these cannot overflow:
5301
        // * `ptr.add(position)`
5302
        // * `position + additional`
5303
        // * `v.len() + additional`
5304
        //
5305
        // `v.len() - position` cannot overflow because we asserted that
5306
        // `position <= v.len()`.
5307
        unsafe {
5308
            // This is a potentially overlapping copy.
5309
            let ptr = v.as_mut_ptr();
5310
            #[allow(clippy::arithmetic_side_effects)]
5311
            ptr.add(position).copy_to(ptr.add(position + additional), v.len() - position);
5312
            ptr.add(position).write_bytes(0, additional);
5313
            #[allow(clippy::arithmetic_side_effects)]
5314
            v.set_len(v.len() + additional);
5315
        }
5316
    }
5317
5318
    #[cfg(test)]
5319
    mod tests {
5320
        use core::convert::TryFrom as _;
5321
5322
        use super::*;
5323
5324
        #[test]
5325
        fn test_extend_vec_zeroed() {
5326
            // Test extending when there is an existing allocation.
5327
            let mut v = vec![100u64, 200, 300];
5328
            extend_vec_zeroed(&mut v, 3);
5329
            assert_eq!(v.len(), 6);
5330
            assert_eq!(&*v, &[100, 200, 300, 0, 0, 0]);
5331
            drop(v);
5332
5333
            // Test extending when there is no existing allocation.
5334
            let mut v: Vec<u64> = Vec::new();
5335
            extend_vec_zeroed(&mut v, 3);
5336
            assert_eq!(v.len(), 3);
5337
            assert_eq!(&*v, &[0, 0, 0]);
5338
            drop(v);
5339
        }
5340
5341
        #[test]
5342
        fn test_extend_vec_zeroed_zst() {
5343
            // Test extending when there is an existing (fake) allocation.
5344
            let mut v = vec![(), (), ()];
5345
            extend_vec_zeroed(&mut v, 3);
5346
            assert_eq!(v.len(), 6);
5347
            assert_eq!(&*v, &[(), (), (), (), (), ()]);
5348
            drop(v);
5349
5350
            // Test extending when there is no existing (fake) allocation.
5351
            let mut v: Vec<()> = Vec::new();
5352
            extend_vec_zeroed(&mut v, 3);
5353
            assert_eq!(&*v, &[(), (), ()]);
5354
            drop(v);
5355
        }
5356
5357
        #[test]
5358
        fn test_insert_vec_zeroed() {
5359
            // Insert at start (no existing allocation).
5360
            let mut v: Vec<u64> = Vec::new();
5361
            insert_vec_zeroed(&mut v, 0, 2);
5362
            assert_eq!(v.len(), 2);
5363
            assert_eq!(&*v, &[0, 0]);
5364
            drop(v);
5365
5366
            // Insert at start.
5367
            let mut v = vec![100u64, 200, 300];
5368
            insert_vec_zeroed(&mut v, 0, 2);
5369
            assert_eq!(v.len(), 5);
5370
            assert_eq!(&*v, &[0, 0, 100, 200, 300]);
5371
            drop(v);
5372
5373
            // Insert at middle.
5374
            let mut v = vec![100u64, 200, 300];
5375
            insert_vec_zeroed(&mut v, 1, 1);
5376
            assert_eq!(v.len(), 4);
5377
            assert_eq!(&*v, &[100, 0, 200, 300]);
5378
            drop(v);
5379
5380
            // Insert at end.
5381
            let mut v = vec![100u64, 200, 300];
5382
            insert_vec_zeroed(&mut v, 3, 1);
5383
            assert_eq!(v.len(), 4);
5384
            assert_eq!(&*v, &[100, 200, 300, 0]);
5385
            drop(v);
5386
        }
5387
5388
        #[test]
5389
        fn test_insert_vec_zeroed_zst() {
5390
            // Insert at start (no existing fake allocation).
5391
            let mut v: Vec<()> = Vec::new();
5392
            insert_vec_zeroed(&mut v, 0, 2);
5393
            assert_eq!(v.len(), 2);
5394
            assert_eq!(&*v, &[(), ()]);
5395
            drop(v);
5396
5397
            // Insert at start.
5398
            let mut v = vec![(), (), ()];
5399
            insert_vec_zeroed(&mut v, 0, 2);
5400
            assert_eq!(v.len(), 5);
5401
            assert_eq!(&*v, &[(), (), (), (), ()]);
5402
            drop(v);
5403
5404
            // Insert at middle.
5405
            let mut v = vec![(), (), ()];
5406
            insert_vec_zeroed(&mut v, 1, 1);
5407
            assert_eq!(v.len(), 4);
5408
            assert_eq!(&*v, &[(), (), (), ()]);
5409
            drop(v);
5410
5411
            // Insert at end.
5412
            let mut v = vec![(), (), ()];
5413
            insert_vec_zeroed(&mut v, 3, 1);
5414
            assert_eq!(v.len(), 4);
5415
            assert_eq!(&*v, &[(), (), (), ()]);
5416
            drop(v);
5417
        }
5418
5419
        #[test]
5420
        fn test_new_box_zeroed() {
5421
            assert_eq!(*u64::new_box_zeroed(), 0);
5422
        }
5423
5424
        #[test]
5425
        fn test_new_box_zeroed_array() {
5426
            drop(<[u32; 0x1000]>::new_box_zeroed());
5427
        }
5428
5429
        #[test]
5430
        fn test_new_box_zeroed_zst() {
5431
            // This test exists in order to exercise unsafe code, especially
5432
            // when running under Miri.
5433
            #[allow(clippy::unit_cmp)]
5434
            {
5435
                assert_eq!(*<()>::new_box_zeroed(), ());
5436
            }
5437
        }
5438
5439
        #[test]
5440
        fn test_new_box_slice_zeroed() {
5441
            let mut s: Box<[u64]> = u64::new_box_slice_zeroed(3);
5442
            assert_eq!(s.len(), 3);
5443
            assert_eq!(&*s, &[0, 0, 0]);
5444
            s[1] = 3;
5445
            assert_eq!(&*s, &[0, 3, 0]);
5446
        }
5447
5448
        #[test]
5449
        fn test_new_box_slice_zeroed_empty() {
5450
            let s: Box<[u64]> = u64::new_box_slice_zeroed(0);
5451
            assert_eq!(s.len(), 0);
5452
        }
5453
5454
        #[test]
5455
        fn test_new_box_slice_zeroed_zst() {
5456
            let mut s: Box<[()]> = <()>::new_box_slice_zeroed(3);
5457
            assert_eq!(s.len(), 3);
5458
            assert!(s.get(10).is_none());
5459
            // This test exists in order to exercise unsafe code, especially
5460
            // when running under Miri.
5461
            #[allow(clippy::unit_cmp)]
5462
            {
5463
                assert_eq!(s[1], ());
5464
            }
5465
            s[2] = ();
5466
        }
5467
5468
        #[test]
5469
        fn test_new_box_slice_zeroed_zst_empty() {
5470
            let s: Box<[()]> = <()>::new_box_slice_zeroed(0);
5471
            assert_eq!(s.len(), 0);
5472
        }
5473
5474
        #[test]
5475
        #[should_panic(expected = "mem::size_of::<Self>() * len overflows `usize`")]
5476
        fn test_new_box_slice_zeroed_panics_mul_overflow() {
5477
            let _ = u16::new_box_slice_zeroed(usize::MAX);
5478
        }
5479
5480
        #[test]
5481
        #[should_panic(expected = "assertion failed: size <= max_alloc")]
5482
        fn test_new_box_slice_zeroed_panics_isize_overflow() {
5483
            let max = usize::try_from(isize::MAX).unwrap();
5484
            let _ = u16::new_box_slice_zeroed((max / mem::size_of::<u16>()) + 1);
5485
        }
5486
    }
5487
}
5488
5489
#[cfg(feature = "alloc")]
5490
#[doc(inline)]
5491
pub use alloc_support::*;
5492
5493
#[cfg(test)]
5494
mod tests {
5495
    #![allow(clippy::unreadable_literal)]
5496
5497
    use core::{cell::UnsafeCell, convert::TryInto as _, ops::Deref};
5498
5499
    use static_assertions::assert_impl_all;
5500
5501
    use super::*;
5502
    use crate::util::testutil::*;
5503
5504
    // An unsized type.
5505
    //
5506
    // This is used to test the custom derives of our traits. The `[u8]` type
5507
    // gets a hand-rolled impl, so it doesn't exercise our custom derives.
5508
    #[derive(Debug, Eq, PartialEq, FromZeroes, FromBytes, AsBytes, Unaligned)]
5509
    #[repr(transparent)]
5510
    struct Unsized([u8]);
5511
5512
    impl Unsized {
5513
        fn from_mut_slice(slc: &mut [u8]) -> &mut Unsized {
5514
            // SAFETY: This *probably* sound - since the layouts of `[u8]` and
5515
            // `Unsized` are the same, so are the layouts of `&mut [u8]` and
5516
            // `&mut Unsized`. [1] Even if it turns out that this isn't actually
5517
            // guaranteed by the language spec, we can just change this since
5518
            // it's in test code.
5519
            //
5520
            // [1] https://github.com/rust-lang/unsafe-code-guidelines/issues/375
5521
            unsafe { mem::transmute(slc) }
5522
        }
5523
    }
5524
5525
    /// Tests of when a sized `DstLayout` is extended with a sized field.
5526
    #[allow(clippy::decimal_literal_representation)]
5527
    #[test]
5528
    fn test_dst_layout_extend_sized_with_sized() {
5529
        // This macro constructs a layout corresponding to a `u8` and extends it
5530
        // with a zero-sized trailing field of given alignment `n`. The macro
5531
        // tests that the resulting layout has both size and alignment `min(n,
5532
        // P)` for all valid values of `repr(packed(P))`.
5533
        macro_rules! test_align_is_size {
5534
            ($n:expr) => {
5535
                let base = DstLayout::for_type::<u8>();
5536
                let trailing_field = DstLayout::for_type::<elain::Align<$n>>();
5537
5538
                let packs =
5539
                    core::iter::once(None).chain((0..29).map(|p| NonZeroUsize::new(2usize.pow(p))));
5540
5541
                for pack in packs {
5542
                    let composite = base.extend(trailing_field, pack);
5543
                    let max_align = pack.unwrap_or(DstLayout::CURRENT_MAX_ALIGN);
5544
                    let align = $n.min(max_align.get());
5545
                    assert_eq!(
5546
                        composite,
5547
                        DstLayout {
5548
                            align: NonZeroUsize::new(align).unwrap(),
5549
                            size_info: SizeInfo::Sized { _size: align }
5550
                        }
5551
                    )
5552
                }
5553
            };
5554
        }
5555
5556
        test_align_is_size!(1);
5557
        test_align_is_size!(2);
5558
        test_align_is_size!(4);
5559
        test_align_is_size!(8);
5560
        test_align_is_size!(16);
5561
        test_align_is_size!(32);
5562
        test_align_is_size!(64);
5563
        test_align_is_size!(128);
5564
        test_align_is_size!(256);
5565
        test_align_is_size!(512);
5566
        test_align_is_size!(1024);
5567
        test_align_is_size!(2048);
5568
        test_align_is_size!(4096);
5569
        test_align_is_size!(8192);
5570
        test_align_is_size!(16384);
5571
        test_align_is_size!(32768);
5572
        test_align_is_size!(65536);
5573
        test_align_is_size!(131072);
5574
        test_align_is_size!(262144);
5575
        test_align_is_size!(524288);
5576
        test_align_is_size!(1048576);
5577
        test_align_is_size!(2097152);
5578
        test_align_is_size!(4194304);
5579
        test_align_is_size!(8388608);
5580
        test_align_is_size!(16777216);
5581
        test_align_is_size!(33554432);
5582
        test_align_is_size!(67108864);
5583
        test_align_is_size!(33554432);
5584
        test_align_is_size!(134217728);
5585
        test_align_is_size!(268435456);
5586
    }
5587
5588
    /// Tests of when a sized `DstLayout` is extended with a DST field.
5589
    #[test]
5590
    fn test_dst_layout_extend_sized_with_dst() {
5591
        // Test that for all combinations of real-world alignments and
5592
        // `repr_packed` values, that the extension of a sized `DstLayout`` with
5593
        // a DST field correctly computes the trailing offset in the composite
5594
        // layout.
5595
5596
        let aligns = (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap());
5597
        let packs = core::iter::once(None).chain(aligns.clone().map(Some));
5598
5599
        for align in aligns {
5600
            for pack in packs.clone() {
5601
                let base = DstLayout::for_type::<u8>();
5602
                let elem_size = 42;
5603
                let trailing_field_offset = 11;
5604
5605
                let trailing_field = DstLayout {
5606
                    align,
5607
                    size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5608
                        _elem_size: elem_size,
5609
                        _offset: 11,
5610
                    }),
5611
                };
5612
5613
                let composite = base.extend(trailing_field, pack);
5614
5615
                let max_align = pack.unwrap_or(DstLayout::CURRENT_MAX_ALIGN).get();
5616
5617
                let align = align.get().min(max_align);
5618
5619
                assert_eq!(
5620
                    composite,
5621
                    DstLayout {
5622
                        align: NonZeroUsize::new(align).unwrap(),
5623
                        size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5624
                            _elem_size: elem_size,
5625
                            _offset: align + trailing_field_offset,
5626
                        }),
5627
                    }
5628
                )
5629
            }
5630
        }
5631
    }
5632
5633
    /// Tests that calling `pad_to_align` on a sized `DstLayout` adds the
5634
    /// expected amount of trailing padding.
5635
    #[test]
5636
    fn test_dst_layout_pad_to_align_with_sized() {
5637
        // For all valid alignments `align`, construct a one-byte layout aligned
5638
        // to `align`, call `pad_to_align`, and assert that the size of the
5639
        // resulting layout is equal to `align`.
5640
        for align in (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap()) {
5641
            let layout = DstLayout { align, size_info: SizeInfo::Sized { _size: 1 } };
5642
5643
            assert_eq!(
5644
                layout.pad_to_align(),
5645
                DstLayout { align, size_info: SizeInfo::Sized { _size: align.get() } }
5646
            );
5647
        }
5648
5649
        // Test explicitly-provided combinations of unpadded and padded
5650
        // counterparts.
5651
5652
        macro_rules! test {
5653
            (unpadded { size: $unpadded_size:expr, align: $unpadded_align:expr }
5654
                => padded { size: $padded_size:expr, align: $padded_align:expr }) => {
5655
                let unpadded = DstLayout {
5656
                    align: NonZeroUsize::new($unpadded_align).unwrap(),
5657
                    size_info: SizeInfo::Sized { _size: $unpadded_size },
5658
                };
5659
                let padded = unpadded.pad_to_align();
5660
5661
                assert_eq!(
5662
                    padded,
5663
                    DstLayout {
5664
                        align: NonZeroUsize::new($padded_align).unwrap(),
5665
                        size_info: SizeInfo::Sized { _size: $padded_size },
5666
                    }
5667
                );
5668
            };
5669
        }
5670
5671
        test!(unpadded { size: 0, align: 4 } => padded { size: 0, align: 4 });
5672
        test!(unpadded { size: 1, align: 4 } => padded { size: 4, align: 4 });
5673
        test!(unpadded { size: 2, align: 4 } => padded { size: 4, align: 4 });
5674
        test!(unpadded { size: 3, align: 4 } => padded { size: 4, align: 4 });
5675
        test!(unpadded { size: 4, align: 4 } => padded { size: 4, align: 4 });
5676
        test!(unpadded { size: 5, align: 4 } => padded { size: 8, align: 4 });
5677
        test!(unpadded { size: 6, align: 4 } => padded { size: 8, align: 4 });
5678
        test!(unpadded { size: 7, align: 4 } => padded { size: 8, align: 4 });
5679
        test!(unpadded { size: 8, align: 4 } => padded { size: 8, align: 4 });
5680
5681
        let current_max_align = DstLayout::CURRENT_MAX_ALIGN.get();
5682
5683
        test!(unpadded { size: 1, align: current_max_align }
5684
            => padded { size: current_max_align, align: current_max_align });
5685
5686
        test!(unpadded { size: current_max_align + 1, align: current_max_align }
5687
            => padded { size: current_max_align * 2, align: current_max_align });
5688
    }
5689
5690
    /// Tests that calling `pad_to_align` on a DST `DstLayout` is a no-op.
5691
    #[test]
5692
    fn test_dst_layout_pad_to_align_with_dst() {
5693
        for align in (0..29).map(|p| NonZeroUsize::new(2usize.pow(p)).unwrap()) {
5694
            for offset in 0..10 {
5695
                for elem_size in 0..10 {
5696
                    let layout = DstLayout {
5697
                        align,
5698
                        size_info: SizeInfo::SliceDst(TrailingSliceLayout {
5699
                            _offset: offset,
5700
                            _elem_size: elem_size,
5701
                        }),
5702
                    };
5703
                    assert_eq!(layout.pad_to_align(), layout);
5704
                }
5705
            }
5706
        }
5707
    }
5708
5709
    // This test takes a long time when running under Miri, so we skip it in
5710
    // that case. This is acceptable because this is a logic test that doesn't
5711
    // attempt to expose UB.
5712
    #[test]
5713
    #[cfg_attr(miri, ignore)]
5714
    fn testvalidate_cast_and_convert_metadata() {
5715
        impl From<usize> for SizeInfo {
5716
            fn from(_size: usize) -> SizeInfo {
5717
                SizeInfo::Sized { _size }
5718
            }
5719
        }
5720
5721
        impl From<(usize, usize)> for SizeInfo {
5722
            fn from((_offset, _elem_size): (usize, usize)) -> SizeInfo {
5723
                SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size })
5724
            }
5725
        }
5726
5727
        fn layout<S: Into<SizeInfo>>(s: S, align: usize) -> DstLayout {
5728
            DstLayout { size_info: s.into(), align: NonZeroUsize::new(align).unwrap() }
5729
        }
5730
5731
        /// This macro accepts arguments in the form of:
5732
        ///
5733
        ///           layout(_, _, _).validate(_, _, _), Ok(Some((_, _)))
5734
        ///                  |  |  |           |  |  |            |  |
5735
        ///    base_size ----+  |  |           |  |  |            |  |
5736
        ///    align -----------+  |           |  |  |            |  |
5737
        ///    trailing_size ------+           |  |  |            |  |
5738
        ///    addr ---------------------------+  |  |            |  |
5739
        ///    bytes_len -------------------------+  |            |  |
5740
        ///    cast_type ----------------------------+            |  |
5741
        ///    elems ---------------------------------------------+  |
5742
        ///    split_at ---------------------------------------------+
5743
        ///
5744
        /// `.validate` is shorthand for `.validate_cast_and_convert_metadata`
5745
        /// for brevity.
5746
        ///
5747
        /// Each argument can either be an iterator or a wildcard. Each
5748
        /// wildcarded variable is implicitly replaced by an iterator over a
5749
        /// representative sample of values for that variable. Each `test!`
5750
        /// invocation iterates over every combination of values provided by
5751
        /// each variable's iterator (ie, the cartesian product) and validates
5752
        /// that the results are expected.
5753
        ///
5754
        /// The final argument uses the same syntax, but it has a different
5755
        /// meaning:
5756
        /// - If it is `Ok(pat)`, then the pattern `pat` is supplied to
5757
        ///   `assert_matches!` to validate the computed result for each
5758
        ///   combination of input values.
5759
        /// - If it is `Err(msg)`, then `test!` validates that the call to
5760
        ///   `validate_cast_and_convert_metadata` panics with the given panic
5761
        ///   message.
5762
        ///
5763
        /// Note that the meta-variables that match these variables have the
5764
        /// `tt` type, and some valid expressions are not valid `tt`s (such as
5765
        /// `a..b`). In this case, wrap the expression in parentheses, and it
5766
        /// will become valid `tt`.
5767
        macro_rules! test {
5768
            ($(:$sizes:expr =>)?
5769
                layout($size:tt, $align:tt)
5770
                .validate($addr:tt, $bytes_len:tt, $cast_type:tt), $expect:pat $(,)?
5771
            ) => {
5772
                itertools::iproduct!(
5773
                    test!(@generate_size $size),
5774
                    test!(@generate_align $align),
5775
                    test!(@generate_usize $addr),
5776
                    test!(@generate_usize $bytes_len),
5777
                    test!(@generate_cast_type $cast_type)
5778
                ).for_each(|(size_info, align, addr, bytes_len, cast_type)| {
5779
                    // Temporarily disable the panic hook installed by the test
5780
                    // harness. If we don't do this, all panic messages will be
5781
                    // kept in an internal log. On its own, this isn't a
5782
                    // problem, but if a non-caught panic ever happens (ie, in
5783
                    // code later in this test not in this macro), all of the
5784
                    // previously-buffered messages will be dumped, hiding the
5785
                    // real culprit.
5786
                    let previous_hook = std::panic::take_hook();
5787
                    // I don't understand why, but this seems to be required in
5788
                    // addition to the previous line.
5789
                    std::panic::set_hook(Box::new(|_| {}));
5790
                    let actual = std::panic::catch_unwind(|| {
5791
                        layout(size_info, align).validate_cast_and_convert_metadata(addr, bytes_len, cast_type)
5792
                    }).map_err(|d| {
5793
                        *d.downcast::<&'static str>().expect("expected string panic message").as_ref()
5794
                    });
5795
                    std::panic::set_hook(previous_hook);
5796
5797
                    assert_matches::assert_matches!(
5798
                        actual, $expect,
5799
                        "layout({size_info:?}, {align}).validate_cast_and_convert_metadata({addr}, {bytes_len}, {cast_type:?})",
5800
                    );
5801
                });
5802
            };
5803
            (@generate_usize _) => { 0..8 };
5804
            // Generate sizes for both Sized and !Sized types.
5805
            (@generate_size _) => {
5806
                test!(@generate_size (_)).chain(test!(@generate_size (_, _)))
5807
            };
5808
            // Generate sizes for both Sized and !Sized types by chaining
5809
            // specified iterators for each.
5810
            (@generate_size ($sized_sizes:tt | $unsized_sizes:tt)) => {
5811
                test!(@generate_size ($sized_sizes)).chain(test!(@generate_size $unsized_sizes))
5812
            };
5813
            // Generate sizes for Sized types.
5814
            (@generate_size (_)) => { test!(@generate_size (0..8)) };
5815
            (@generate_size ($sizes:expr)) => { $sizes.into_iter().map(Into::<SizeInfo>::into) };
5816
            // Generate sizes for !Sized types.
5817
            (@generate_size ($min_sizes:tt, $elem_sizes:tt)) => {
5818
                itertools::iproduct!(
5819
                    test!(@generate_min_size $min_sizes),
5820
                    test!(@generate_elem_size $elem_sizes)
5821
                ).map(Into::<SizeInfo>::into)
5822
            };
5823
            (@generate_fixed_size _) => { (0..8).into_iter().map(Into::<SizeInfo>::into) };
5824
            (@generate_min_size _) => { 0..8 };
5825
            (@generate_elem_size _) => { 1..8 };
5826
            (@generate_align _) => { [1, 2, 4, 8, 16] };
5827
            (@generate_opt_usize _) => { [None].into_iter().chain((0..8).map(Some).into_iter()) };
5828
            (@generate_cast_type _) => { [_CastType::_Prefix, _CastType::_Suffix] };
5829
            (@generate_cast_type $variant:ident) => { [_CastType::$variant] };
5830
            // Some expressions need to be wrapped in parentheses in order to be
5831
            // valid `tt`s (required by the top match pattern). See the comment
5832
            // below for more details. This arm removes these parentheses to
5833
            // avoid generating an `unused_parens` warning.
5834
            (@$_:ident ($vals:expr)) => { $vals };
5835
            (@$_:ident $vals:expr) => { $vals };
5836
        }
5837
5838
        const EVENS: [usize; 8] = [0, 2, 4, 6, 8, 10, 12, 14];
5839
        const ODDS: [usize; 8] = [1, 3, 5, 7, 9, 11, 13, 15];
5840
5841
        // base_size is too big for the memory region.
5842
        test!(layout(((1..8) | ((1..8), (1..8))), _).validate(_, [0], _), Ok(None));
5843
        test!(layout(((2..8) | ((2..8), (2..8))), _).validate(_, [1], _), Ok(None));
5844
5845
        // addr is unaligned for prefix cast
5846
        test!(layout(_, [2]).validate(ODDS, _, _Prefix), Ok(None));
5847
        test!(layout(_, [2]).validate(ODDS, _, _Prefix), Ok(None));
5848
5849
        // addr is aligned, but end of buffer is unaligned for suffix cast
5850
        test!(layout(_, [2]).validate(EVENS, ODDS, _Suffix), Ok(None));
5851
        test!(layout(_, [2]).validate(EVENS, ODDS, _Suffix), Ok(None));
5852
5853
        // Unfortunately, these constants cannot easily be used in the
5854
        // implementation of `validate_cast_and_convert_metadata`, since
5855
        // `panic!` consumes a string literal, not an expression.
5856
        //
5857
        // It's important that these messages be in a separate module. If they
5858
        // were at the function's top level, we'd pass them to `test!` as, e.g.,
5859
        // `Err(TRAILING)`, which would run into a subtle Rust footgun - the
5860
        // `TRAILING` identifier would be treated as a pattern to match rather
5861
        // than a value to check for equality.
5862
        mod msgs {
5863
            pub(super) const TRAILING: &str =
5864
                "attempted to cast to slice type with zero-sized element";
5865
            pub(super) const OVERFLOW: &str = "`addr` + `bytes_len` > usize::MAX";
5866
        }
5867
5868
        // casts with ZST trailing element types are unsupported
5869
        test!(layout((_, [0]), _).validate(_, _, _), Err(msgs::TRAILING),);
5870
5871
        // addr + bytes_len must not overflow usize
5872
        test!(layout(_, _).validate([usize::MAX], (1..100), _), Err(msgs::OVERFLOW));
5873
        test!(layout(_, _).validate((1..100), [usize::MAX], _), Err(msgs::OVERFLOW));
5874
        test!(
5875
            layout(_, _).validate(
5876
                [usize::MAX / 2 + 1, usize::MAX],
5877
                [usize::MAX / 2 + 1, usize::MAX],
5878
                _
5879
            ),
5880
            Err(msgs::OVERFLOW)
5881
        );
5882
5883
        // Validates that `validate_cast_and_convert_metadata` satisfies its own
5884
        // documented safety postconditions, and also a few other properties
5885
        // that aren't documented but we want to guarantee anyway.
5886
        fn validate_behavior(
5887
            (layout, addr, bytes_len, cast_type): (DstLayout, usize, usize, _CastType),
5888
        ) {
5889
            if let Some((elems, split_at)) =
5890
                layout.validate_cast_and_convert_metadata(addr, bytes_len, cast_type)
5891
            {
5892
                let (size_info, align) = (layout.size_info, layout.align);
5893
                let debug_str = format!(
5894
                    "layout({size_info:?}, {align}).validate_cast_and_convert_metadata({addr}, {bytes_len}, {cast_type:?}) => ({elems}, {split_at})",
5895
                );
5896
5897
                // If this is a sized type (no trailing slice), then `elems` is
5898
                // meaningless, but in practice we set it to 0. Callers are not
5899
                // allowed to rely on this, but a lot of math is nicer if
5900
                // they're able to, and some callers might accidentally do that.
5901
                let sized = matches!(layout.size_info, SizeInfo::Sized { .. });
5902
                assert!(!(sized && elems != 0), "{}", debug_str);
5903
5904
                let resulting_size = match layout.size_info {
5905
                    SizeInfo::Sized { _size } => _size,
5906
                    SizeInfo::SliceDst(TrailingSliceLayout {
5907
                        _offset: offset,
5908
                        _elem_size: elem_size,
5909
                    }) => {
5910
                        let padded_size = |elems| {
5911
                            let without_padding = offset + elems * elem_size;
5912
                            without_padding
5913
                                + util::core_layout::padding_needed_for(without_padding, align)
5914
                        };
5915
5916
                        let resulting_size = padded_size(elems);
5917
                        // Test that `validate_cast_and_convert_metadata`
5918
                        // computed the largest possible value that fits in the
5919
                        // given range.
5920
                        assert!(padded_size(elems + 1) > bytes_len, "{}", debug_str);
5921
                        resulting_size
5922
                    }
5923
                };
5924
5925
                // Test safety postconditions guaranteed by
5926
                // `validate_cast_and_convert_metadata`.
5927
                assert!(resulting_size <= bytes_len, "{}", debug_str);
5928
                match cast_type {
5929
                    _CastType::_Prefix => {
5930
                        assert_eq!(addr % align, 0, "{}", debug_str);
5931
                        assert_eq!(resulting_size, split_at, "{}", debug_str);
5932
                    }
5933
                    _CastType::_Suffix => {
5934
                        assert_eq!(split_at, bytes_len - resulting_size, "{}", debug_str);
5935
                        assert_eq!((addr + split_at) % align, 0, "{}", debug_str);
5936
                    }
5937
                }
5938
            } else {
5939
                let min_size = match layout.size_info {
5940
                    SizeInfo::Sized { _size } => _size,
5941
                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, .. }) => {
5942
                        _offset + util::core_layout::padding_needed_for(_offset, layout.align)
5943
                    }
5944
                };
5945
5946
                // If a cast is invalid, it is either because...
5947
                // 1. there are insufficent bytes at the given region for type:
5948
                let insufficient_bytes = bytes_len < min_size;
5949
                // 2. performing the cast would misalign type:
5950
                let base = match cast_type {
5951
                    _CastType::_Prefix => 0,
5952
                    _CastType::_Suffix => bytes_len,
5953
                };
5954
                let misaligned = (base + addr) % layout.align != 0;
5955
5956
                assert!(insufficient_bytes || misaligned);
5957
            }
5958
        }
5959
5960
        let sizes = 0..8;
5961
        let elem_sizes = 1..8;
5962
        let size_infos = sizes
5963
            .clone()
5964
            .map(Into::<SizeInfo>::into)
5965
            .chain(itertools::iproduct!(sizes, elem_sizes).map(Into::<SizeInfo>::into));
5966
        let layouts = itertools::iproduct!(size_infos, [1, 2, 4, 8, 16, 32])
5967
            .filter(|(size_info, align)| !matches!(size_info, SizeInfo::Sized { _size } if _size % align != 0))
5968
            .map(|(size_info, align)| layout(size_info, align));
5969
        itertools::iproduct!(layouts, 0..8, 0..8, [_CastType::_Prefix, _CastType::_Suffix])
5970
            .for_each(validate_behavior);
5971
    }
5972
5973
    #[test]
5974
    #[cfg(__INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS)]
5975
    fn test_validate_rust_layout() {
5976
        use core::ptr::NonNull;
5977
5978
        // This test synthesizes pointers with various metadata and uses Rust's
5979
        // built-in APIs to confirm that Rust makes decisions about type layout
5980
        // which are consistent with what we believe is guaranteed by the
5981
        // language. If this test fails, it doesn't just mean our code is wrong
5982
        // - it means we're misunderstanding the language's guarantees.
5983
5984
        #[derive(Debug)]
5985
        struct MacroArgs {
5986
            offset: usize,
5987
            align: NonZeroUsize,
5988
            elem_size: Option<usize>,
5989
        }
5990
5991
        /// # Safety
5992
        ///
5993
        /// `test` promises to only call `addr_of_slice_field` on a `NonNull<T>`
5994
        /// which points to a valid `T`.
5995
        ///
5996
        /// `with_elems` must produce a pointer which points to a valid `T`.
5997
        fn test<T: ?Sized, W: Fn(usize) -> NonNull<T>>(
5998
            args: MacroArgs,
5999
            with_elems: W,
6000
            addr_of_slice_field: Option<fn(NonNull<T>) -> NonNull<u8>>,
6001
        ) {
6002
            let dst = args.elem_size.is_some();
6003
            let layout = {
6004
                let size_info = match args.elem_size {
6005
                    Some(elem_size) => SizeInfo::SliceDst(TrailingSliceLayout {
6006
                        _offset: args.offset,
6007
                        _elem_size: elem_size,
6008
                    }),
6009
                    None => SizeInfo::Sized {
6010
                        // Rust only supports types whose sizes are a multiple
6011
                        // of their alignment. If the macro created a type like
6012
                        // this:
6013
                        //
6014
                        //   #[repr(C, align(2))]
6015
                        //   struct Foo([u8; 1]);
6016
                        //
6017
                        // ...then Rust will automatically round the type's size
6018
                        // up to 2.
6019
                        _size: args.offset
6020
                            + util::core_layout::padding_needed_for(args.offset, args.align),
6021
                    },
6022
                };
6023
                DstLayout { size_info, align: args.align }
6024
            };
6025
6026
            for elems in 0..128 {
6027
                let ptr = with_elems(elems);
6028
6029
                if let Some(addr_of_slice_field) = addr_of_slice_field {
6030
                    let slc_field_ptr = addr_of_slice_field(ptr).as_ptr();
6031
                    // SAFETY: Both `slc_field_ptr` and `ptr` are pointers to
6032
                    // the same valid Rust object.
6033
                    let offset: usize =
6034
                        unsafe { slc_field_ptr.byte_offset_from(ptr.as_ptr()).try_into().unwrap() };
6035
                    assert_eq!(offset, args.offset);
6036
                }
6037
6038
                // SAFETY: `ptr` points to a valid `T`.
6039
                let (size, align) = unsafe {
6040
                    (mem::size_of_val_raw(ptr.as_ptr()), mem::align_of_val_raw(ptr.as_ptr()))
6041
                };
6042
6043
                // Avoid expensive allocation when running under Miri.
6044
                let assert_msg = if !cfg!(miri) {
6045
                    format!("\n{args:?}\nsize:{size}, align:{align}")
6046
                } else {
6047
                    String::new()
6048
                };
6049
6050
                let without_padding =
6051
                    args.offset + args.elem_size.map(|elem_size| elems * elem_size).unwrap_or(0);
6052
                assert!(size >= without_padding, "{}", assert_msg);
6053
                assert_eq!(align, args.align.get(), "{}", assert_msg);
6054
6055
                // This encodes the most important part of the test: our
6056
                // understanding of how Rust determines the layout of repr(C)
6057
                // types. Sized repr(C) types are trivial, but DST types have
6058
                // some subtlety. Note that:
6059
                // - For sized types, `without_padding` is just the size of the
6060
                //   type that we constructed for `Foo`. Since we may have
6061
                //   requested a larger alignment, `Foo` may actually be larger
6062
                //   than this, hence `padding_needed_for`.
6063
                // - For unsized types, `without_padding` is dynamically
6064
                //   computed from the offset, the element size, and element
6065
                //   count. We expect that the size of the object should be
6066
                //   `offset + elem_size * elems` rounded up to the next
6067
                //   alignment.
6068
                let expected_size = without_padding
6069
                    + util::core_layout::padding_needed_for(without_padding, args.align);
6070
                assert_eq!(expected_size, size, "{}", assert_msg);
6071
6072
                // For zero-sized element types,
6073
                // `validate_cast_and_convert_metadata` just panics, so we skip
6074
                // testing those types.
6075
                if args.elem_size.map(|elem_size| elem_size > 0).unwrap_or(true) {
6076
                    let addr = ptr.addr().get();
6077
                    let (got_elems, got_split_at) = layout
6078
                        .validate_cast_and_convert_metadata(addr, size, _CastType::_Prefix)
6079
                        .unwrap();
6080
                    // Avoid expensive allocation when running under Miri.
6081
                    let assert_msg = if !cfg!(miri) {
6082
                        format!(
6083
                            "{}\nvalidate_cast_and_convert_metadata({addr}, {size})",
6084
                            assert_msg
6085
                        )
6086
                    } else {
6087
                        String::new()
6088
                    };
6089
                    assert_eq!(got_split_at, size, "{}", assert_msg);
6090
                    if dst {
6091
                        assert!(got_elems >= elems, "{}", assert_msg);
6092
                        if got_elems != elems {
6093
                            // If `validate_cast_and_convert_metadata`
6094
                            // returned more elements than `elems`, that
6095
                            // means that `elems` is not the maximum number
6096
                            // of elements that can fit in `size` - in other
6097
                            // words, there is enough padding at the end of
6098
                            // the value to fit at least one more element.
6099
                            // If we use this metadata to synthesize a
6100
                            // pointer, despite having a different element
6101
                            // count, we still expect it to have the same
6102
                            // size.
6103
                            let got_ptr = with_elems(got_elems);
6104
                            // SAFETY: `got_ptr` is a pointer to a valid `T`.
6105
                            let size_of_got_ptr = unsafe { mem::size_of_val_raw(got_ptr.as_ptr()) };
6106
                            assert_eq!(size_of_got_ptr, size, "{}", assert_msg);
6107
                        }
6108
                    } else {
6109
                        // For sized casts, the returned element value is
6110
                        // technically meaningless, and we don't guarantee any
6111
                        // particular value. In practice, it's always zero.
6112
                        assert_eq!(got_elems, 0, "{}", assert_msg)
6113
                    }
6114
                }
6115
            }
6116
        }
6117
6118
        macro_rules! validate_against_rust {
6119
            ($offset:literal, $align:literal $(, $elem_size:literal)?) => {{
6120
                #[repr(C, align($align))]
6121
                struct Foo([u8; $offset]$(, [[u8; $elem_size]])?);
6122
6123
                let args = MacroArgs {
6124
                    offset: $offset,
6125
                    align: $align.try_into().unwrap(),
6126
                    elem_size: {
6127
                        #[allow(unused)]
6128
                        let ret = None::<usize>;
6129
                        $(let ret = Some($elem_size);)?
6130
                        ret
6131
                    }
6132
                };
6133
6134
                #[repr(C, align($align))]
6135
                struct FooAlign;
6136
                // Create an aligned buffer to use in order to synthesize
6137
                // pointers to `Foo`. We don't ever load values from these
6138
                // pointers - we just do arithmetic on them - so having a "real"
6139
                // block of memory as opposed to a validly-aligned-but-dangling
6140
                // pointer is only necessary to make Miri happy since we run it
6141
                // with "strict provenance" checking enabled.
6142
                let aligned_buf = Align::<_, FooAlign>::new([0u8; 1024]);
6143
                let with_elems = |elems| {
6144
                    let slc = NonNull::slice_from_raw_parts(NonNull::from(&aligned_buf.t), elems);
6145
                    #[allow(clippy::as_conversions)]
6146
                    NonNull::new(slc.as_ptr() as *mut Foo).unwrap()
6147
                };
6148
                let addr_of_slice_field = {
6149
                    #[allow(unused)]
6150
                    let f = None::<fn(NonNull<Foo>) -> NonNull<u8>>;
6151
                    $(
6152
                        // SAFETY: `test` promises to only call `f` with a `ptr`
6153
                        // to a valid `Foo`.
6154
                        let f: Option<fn(NonNull<Foo>) -> NonNull<u8>> = Some(|ptr: NonNull<Foo>| unsafe {
6155
                            NonNull::new(ptr::addr_of_mut!((*ptr.as_ptr()).1)).unwrap().cast::<u8>()
6156
                        });
6157
                        let _ = $elem_size;
6158
                    )?
6159
                    f
6160
                };
6161
6162
                test::<Foo, _>(args, with_elems, addr_of_slice_field);
6163
            }};
6164
        }
6165
6166
        // Every permutation of:
6167
        // - offset in [0, 4]
6168
        // - align in [1, 16]
6169
        // - elem_size in [0, 4] (plus no elem_size)
6170
        validate_against_rust!(0, 1);
6171
        validate_against_rust!(0, 1, 0);
6172
        validate_against_rust!(0, 1, 1);
6173
        validate_against_rust!(0, 1, 2);
6174
        validate_against_rust!(0, 1, 3);
6175
        validate_against_rust!(0, 1, 4);
6176
        validate_against_rust!(0, 2);
6177
        validate_against_rust!(0, 2, 0);
6178
        validate_against_rust!(0, 2, 1);
6179
        validate_against_rust!(0, 2, 2);
6180
        validate_against_rust!(0, 2, 3);
6181
        validate_against_rust!(0, 2, 4);
6182
        validate_against_rust!(0, 4);
6183
        validate_against_rust!(0, 4, 0);
6184
        validate_against_rust!(0, 4, 1);
6185
        validate_against_rust!(0, 4, 2);
6186
        validate_against_rust!(0, 4, 3);
6187
        validate_against_rust!(0, 4, 4);
6188
        validate_against_rust!(0, 8);
6189
        validate_against_rust!(0, 8, 0);
6190
        validate_against_rust!(0, 8, 1);
6191
        validate_against_rust!(0, 8, 2);
6192
        validate_against_rust!(0, 8, 3);
6193
        validate_against_rust!(0, 8, 4);
6194
        validate_against_rust!(0, 16);
6195
        validate_against_rust!(0, 16, 0);
6196
        validate_against_rust!(0, 16, 1);
6197
        validate_against_rust!(0, 16, 2);
6198
        validate_against_rust!(0, 16, 3);
6199
        validate_against_rust!(0, 16, 4);
6200
        validate_against_rust!(1, 1);
6201
        validate_against_rust!(1, 1, 0);
6202
        validate_against_rust!(1, 1, 1);
6203
        validate_against_rust!(1, 1, 2);
6204
        validate_against_rust!(1, 1, 3);
6205
        validate_against_rust!(1, 1, 4);
6206
        validate_against_rust!(1, 2);
6207
        validate_against_rust!(1, 2, 0);
6208
        validate_against_rust!(1, 2, 1);
6209
        validate_against_rust!(1, 2, 2);
6210
        validate_against_rust!(1, 2, 3);
6211
        validate_against_rust!(1, 2, 4);
6212
        validate_against_rust!(1, 4);
6213
        validate_against_rust!(1, 4, 0);
6214
        validate_against_rust!(1, 4, 1);
6215
        validate_against_rust!(1, 4, 2);
6216
        validate_against_rust!(1, 4, 3);
6217
        validate_against_rust!(1, 4, 4);
6218
        validate_against_rust!(1, 8);
6219
        validate_against_rust!(1, 8, 0);
6220
        validate_against_rust!(1, 8, 1);
6221
        validate_against_rust!(1, 8, 2);
6222
        validate_against_rust!(1, 8, 3);
6223
        validate_against_rust!(1, 8, 4);
6224
        validate_against_rust!(1, 16);
6225
        validate_against_rust!(1, 16, 0);
6226
        validate_against_rust!(1, 16, 1);
6227
        validate_against_rust!(1, 16, 2);
6228
        validate_against_rust!(1, 16, 3);
6229
        validate_against_rust!(1, 16, 4);
6230
        validate_against_rust!(2, 1);
6231
        validate_against_rust!(2, 1, 0);
6232
        validate_against_rust!(2, 1, 1);
6233
        validate_against_rust!(2, 1, 2);
6234
        validate_against_rust!(2, 1, 3);
6235
        validate_against_rust!(2, 1, 4);
6236
        validate_against_rust!(2, 2);
6237
        validate_against_rust!(2, 2, 0);
6238
        validate_against_rust!(2, 2, 1);
6239
        validate_against_rust!(2, 2, 2);
6240
        validate_against_rust!(2, 2, 3);
6241
        validate_against_rust!(2, 2, 4);
6242
        validate_against_rust!(2, 4);
6243
        validate_against_rust!(2, 4, 0);
6244
        validate_against_rust!(2, 4, 1);
6245
        validate_against_rust!(2, 4, 2);
6246
        validate_against_rust!(2, 4, 3);
6247
        validate_against_rust!(2, 4, 4);
6248
        validate_against_rust!(2, 8);
6249
        validate_against_rust!(2, 8, 0);
6250
        validate_against_rust!(2, 8, 1);
6251
        validate_against_rust!(2, 8, 2);
6252
        validate_against_rust!(2, 8, 3);
6253
        validate_against_rust!(2, 8, 4);
6254
        validate_against_rust!(2, 16);
6255
        validate_against_rust!(2, 16, 0);
6256
        validate_against_rust!(2, 16, 1);
6257
        validate_against_rust!(2, 16, 2);
6258
        validate_against_rust!(2, 16, 3);
6259
        validate_against_rust!(2, 16, 4);
6260
        validate_against_rust!(3, 1);
6261
        validate_against_rust!(3, 1, 0);
6262
        validate_against_rust!(3, 1, 1);
6263
        validate_against_rust!(3, 1, 2);
6264
        validate_against_rust!(3, 1, 3);
6265
        validate_against_rust!(3, 1, 4);
6266
        validate_against_rust!(3, 2);
6267
        validate_against_rust!(3, 2, 0);
6268
        validate_against_rust!(3, 2, 1);
6269
        validate_against_rust!(3, 2, 2);
6270
        validate_against_rust!(3, 2, 3);
6271
        validate_against_rust!(3, 2, 4);
6272
        validate_against_rust!(3, 4);
6273
        validate_against_rust!(3, 4, 0);
6274
        validate_against_rust!(3, 4, 1);
6275
        validate_against_rust!(3, 4, 2);
6276
        validate_against_rust!(3, 4, 3);
6277
        validate_against_rust!(3, 4, 4);
6278
        validate_against_rust!(3, 8);
6279
        validate_against_rust!(3, 8, 0);
6280
        validate_against_rust!(3, 8, 1);
6281
        validate_against_rust!(3, 8, 2);
6282
        validate_against_rust!(3, 8, 3);
6283
        validate_against_rust!(3, 8, 4);
6284
        validate_against_rust!(3, 16);
6285
        validate_against_rust!(3, 16, 0);
6286
        validate_against_rust!(3, 16, 1);
6287
        validate_against_rust!(3, 16, 2);
6288
        validate_against_rust!(3, 16, 3);
6289
        validate_against_rust!(3, 16, 4);
6290
        validate_against_rust!(4, 1);
6291
        validate_against_rust!(4, 1, 0);
6292
        validate_against_rust!(4, 1, 1);
6293
        validate_against_rust!(4, 1, 2);
6294
        validate_against_rust!(4, 1, 3);
6295
        validate_against_rust!(4, 1, 4);
6296
        validate_against_rust!(4, 2);
6297
        validate_against_rust!(4, 2, 0);
6298
        validate_against_rust!(4, 2, 1);
6299
        validate_against_rust!(4, 2, 2);
6300
        validate_against_rust!(4, 2, 3);
6301
        validate_against_rust!(4, 2, 4);
6302
        validate_against_rust!(4, 4);
6303
        validate_against_rust!(4, 4, 0);
6304
        validate_against_rust!(4, 4, 1);
6305
        validate_against_rust!(4, 4, 2);
6306
        validate_against_rust!(4, 4, 3);
6307
        validate_against_rust!(4, 4, 4);
6308
        validate_against_rust!(4, 8);
6309
        validate_against_rust!(4, 8, 0);
6310
        validate_against_rust!(4, 8, 1);
6311
        validate_against_rust!(4, 8, 2);
6312
        validate_against_rust!(4, 8, 3);
6313
        validate_against_rust!(4, 8, 4);
6314
        validate_against_rust!(4, 16);
6315
        validate_against_rust!(4, 16, 0);
6316
        validate_against_rust!(4, 16, 1);
6317
        validate_against_rust!(4, 16, 2);
6318
        validate_against_rust!(4, 16, 3);
6319
        validate_against_rust!(4, 16, 4);
6320
    }
6321
6322
    #[test]
6323
    fn test_known_layout() {
6324
        // Test that `$ty` and `ManuallyDrop<$ty>` have the expected layout.
6325
        // Test that `PhantomData<$ty>` has the same layout as `()` regardless
6326
        // of `$ty`.
6327
        macro_rules! test {
6328
            ($ty:ty, $expect:expr) => {
6329
                let expect = $expect;
6330
                assert_eq!(<$ty as KnownLayout>::LAYOUT, expect);
6331
                assert_eq!(<ManuallyDrop<$ty> as KnownLayout>::LAYOUT, expect);
6332
                assert_eq!(<PhantomData<$ty> as KnownLayout>::LAYOUT, <() as KnownLayout>::LAYOUT);
6333
            };
6334
        }
6335
6336
        let layout = |offset, align, _trailing_slice_elem_size| DstLayout {
6337
            align: NonZeroUsize::new(align).unwrap(),
6338
            size_info: match _trailing_slice_elem_size {
6339
                None => SizeInfo::Sized { _size: offset },
6340
                Some(elem_size) => SizeInfo::SliceDst(TrailingSliceLayout {
6341
                    _offset: offset,
6342
                    _elem_size: elem_size,
6343
                }),
6344
            },
6345
        };
6346
6347
        test!((), layout(0, 1, None));
6348
        test!(u8, layout(1, 1, None));
6349
        // Use `align_of` because `u64` alignment may be smaller than 8 on some
6350
        // platforms.
6351
        test!(u64, layout(8, mem::align_of::<u64>(), None));
6352
        test!(AU64, layout(8, 8, None));
6353
6354
        test!(Option<&'static ()>, usize::LAYOUT);
6355
6356
        test!([()], layout(0, 1, Some(0)));
6357
        test!([u8], layout(0, 1, Some(1)));
6358
        test!(str, layout(0, 1, Some(1)));
6359
    }
6360
6361
    #[cfg(feature = "derive")]
6362
    #[test]
6363
    fn test_known_layout_derive() {
6364
        // In this and other files (`late_compile_pass.rs`,
6365
        // `mid_compile_pass.rs`, and `struct.rs`), we test success and failure
6366
        // modes of `derive(KnownLayout)` for the following combination of
6367
        // properties:
6368
        //
6369
        // +------------+--------------------------------------+-----------+
6370
        // |            |      trailing field properties       |           |
6371
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6372
        // |------------+----------+----------------+----------+-----------|
6373
        // |          N |        N |              N |        N |      KL00 |
6374
        // |          N |        N |              N |        Y |      KL01 |
6375
        // |          N |        N |              Y |        N |      KL02 |
6376
        // |          N |        N |              Y |        Y |      KL03 |
6377
        // |          N |        Y |              N |        N |      KL04 |
6378
        // |          N |        Y |              N |        Y |      KL05 |
6379
        // |          N |        Y |              Y |        N |      KL06 |
6380
        // |          N |        Y |              Y |        Y |      KL07 |
6381
        // |          Y |        N |              N |        N |      KL08 |
6382
        // |          Y |        N |              N |        Y |      KL09 |
6383
        // |          Y |        N |              Y |        N |      KL10 |
6384
        // |          Y |        N |              Y |        Y |      KL11 |
6385
        // |          Y |        Y |              N |        N |      KL12 |
6386
        // |          Y |        Y |              N |        Y |      KL13 |
6387
        // |          Y |        Y |              Y |        N |      KL14 |
6388
        // |          Y |        Y |              Y |        Y |      KL15 |
6389
        // +------------+----------+----------------+----------+-----------+
6390
6391
        struct NotKnownLayout<T = ()> {
6392
            _t: T,
6393
        }
6394
6395
        #[derive(KnownLayout)]
6396
        #[repr(C)]
6397
        struct AlignSize<const ALIGN: usize, const SIZE: usize>
6398
        where
6399
            elain::Align<ALIGN>: elain::Alignment,
6400
        {
6401
            _align: elain::Align<ALIGN>,
6402
            _size: [u8; SIZE],
6403
        }
6404
6405
        type AU16 = AlignSize<2, 2>;
6406
        type AU32 = AlignSize<4, 4>;
6407
6408
        fn _assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
6409
6410
        let sized_layout = |align, size| DstLayout {
6411
            align: NonZeroUsize::new(align).unwrap(),
6412
            size_info: SizeInfo::Sized { _size: size },
6413
        };
6414
6415
        let unsized_layout = |align, elem_size, offset| DstLayout {
6416
            align: NonZeroUsize::new(align).unwrap(),
6417
            size_info: SizeInfo::SliceDst(TrailingSliceLayout {
6418
                _offset: offset,
6419
                _elem_size: elem_size,
6420
            }),
6421
        };
6422
6423
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6424
        // |          N |        N |              N |        Y |      KL01 |
6425
        #[derive(KnownLayout)]
6426
        #[allow(dead_code)] // fields are never read
6427
        struct KL01(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6428
6429
        let expected = DstLayout::for_type::<KL01>();
6430
6431
        assert_eq!(<KL01 as KnownLayout>::LAYOUT, expected);
6432
        assert_eq!(<KL01 as KnownLayout>::LAYOUT, sized_layout(4, 8));
6433
6434
        // ...with `align(N)`:
6435
        #[derive(KnownLayout)]
6436
        #[repr(align(64))]
6437
        #[allow(dead_code)] // fields are never read
6438
        struct KL01Align(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6439
6440
        let expected = DstLayout::for_type::<KL01Align>();
6441
6442
        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, expected);
6443
        assert_eq!(<KL01Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6444
6445
        // ...with `packed`:
6446
        #[derive(KnownLayout)]
6447
        #[repr(packed)]
6448
        #[allow(dead_code)] // fields are never read
6449
        struct KL01Packed(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6450
6451
        let expected = DstLayout::for_type::<KL01Packed>();
6452
6453
        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, expected);
6454
        assert_eq!(<KL01Packed as KnownLayout>::LAYOUT, sized_layout(1, 6));
6455
6456
        // ...with `packed(N)`:
6457
        #[derive(KnownLayout)]
6458
        #[repr(packed(2))]
6459
        #[allow(dead_code)] // fields are never read
6460
        struct KL01PackedN(NotKnownLayout<AU32>, NotKnownLayout<AU16>);
6461
6462
        assert_impl_all!(KL01PackedN: KnownLayout);
6463
6464
        let expected = DstLayout::for_type::<KL01PackedN>();
6465
6466
        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, expected);
6467
        assert_eq!(<KL01PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6468
6469
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6470
        // |          N |        N |              Y |        Y |      KL03 |
6471
        #[derive(KnownLayout)]
6472
        #[allow(dead_code)] // fields are never read
6473
        struct KL03(NotKnownLayout, u8);
6474
6475
        let expected = DstLayout::for_type::<KL03>();
6476
6477
        assert_eq!(<KL03 as KnownLayout>::LAYOUT, expected);
6478
        assert_eq!(<KL03 as KnownLayout>::LAYOUT, sized_layout(1, 1));
6479
6480
        // ... with `align(N)`
6481
        #[derive(KnownLayout)]
6482
        #[repr(align(64))]
6483
        #[allow(dead_code)] // fields are never read
6484
        struct KL03Align(NotKnownLayout<AU32>, u8);
6485
6486
        let expected = DstLayout::for_type::<KL03Align>();
6487
6488
        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, expected);
6489
        assert_eq!(<KL03Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6490
6491
        // ... with `packed`:
6492
        #[derive(KnownLayout)]
6493
        #[repr(packed)]
6494
        #[allow(dead_code)] // fields are never read
6495
        struct KL03Packed(NotKnownLayout<AU32>, u8);
6496
6497
        let expected = DstLayout::for_type::<KL03Packed>();
6498
6499
        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, expected);
6500
        assert_eq!(<KL03Packed as KnownLayout>::LAYOUT, sized_layout(1, 5));
6501
6502
        // ... with `packed(N)`
6503
        #[derive(KnownLayout)]
6504
        #[repr(packed(2))]
6505
        #[allow(dead_code)] // fields are never read
6506
        struct KL03PackedN(NotKnownLayout<AU32>, u8);
6507
6508
        assert_impl_all!(KL03PackedN: KnownLayout);
6509
6510
        let expected = DstLayout::for_type::<KL03PackedN>();
6511
6512
        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, expected);
6513
        assert_eq!(<KL03PackedN as KnownLayout>::LAYOUT, sized_layout(2, 6));
6514
6515
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6516
        // |          N |        Y |              N |        Y |      KL05 |
6517
        #[derive(KnownLayout)]
6518
        #[allow(dead_code)] // fields are never read
6519
        struct KL05<T>(u8, T);
6520
6521
        fn _test_kl05<T>(t: T) -> impl KnownLayout {
6522
            KL05(0u8, t)
6523
        }
6524
6525
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6526
        // |          N |        Y |              Y |        Y |      KL07 |
6527
        #[derive(KnownLayout)]
6528
        #[allow(dead_code)] // fields are never read
6529
        struct KL07<T: KnownLayout>(u8, T);
6530
6531
        fn _test_kl07<T: KnownLayout>(t: T) -> impl KnownLayout {
6532
            let _ = KL07(0u8, t);
6533
        }
6534
6535
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6536
        // |          Y |        N |              Y |        N |      KL10 |
6537
        #[derive(KnownLayout)]
6538
        #[repr(C)]
6539
        struct KL10(NotKnownLayout<AU32>, [u8]);
6540
6541
        let expected = DstLayout::new_zst(None)
6542
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
6543
            .extend(<[u8] as KnownLayout>::LAYOUT, None)
6544
            .pad_to_align();
6545
6546
        assert_eq!(<KL10 as KnownLayout>::LAYOUT, expected);
6547
        assert_eq!(<KL10 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 4));
6548
6549
        // ...with `align(N)`:
6550
        #[derive(KnownLayout)]
6551
        #[repr(C, align(64))]
6552
        struct KL10Align(NotKnownLayout<AU32>, [u8]);
6553
6554
        let repr_align = NonZeroUsize::new(64);
6555
6556
        let expected = DstLayout::new_zst(repr_align)
6557
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), None)
6558
            .extend(<[u8] as KnownLayout>::LAYOUT, None)
6559
            .pad_to_align();
6560
6561
        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, expected);
6562
        assert_eq!(<KL10Align as KnownLayout>::LAYOUT, unsized_layout(64, 1, 4));
6563
6564
        // ...with `packed`:
6565
        #[derive(KnownLayout)]
6566
        #[repr(C, packed)]
6567
        struct KL10Packed(NotKnownLayout<AU32>, [u8]);
6568
6569
        let repr_packed = NonZeroUsize::new(1);
6570
6571
        let expected = DstLayout::new_zst(None)
6572
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
6573
            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
6574
            .pad_to_align();
6575
6576
        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, expected);
6577
        assert_eq!(<KL10Packed as KnownLayout>::LAYOUT, unsized_layout(1, 1, 4));
6578
6579
        // ...with `packed(N)`:
6580
        #[derive(KnownLayout)]
6581
        #[repr(C, packed(2))]
6582
        struct KL10PackedN(NotKnownLayout<AU32>, [u8]);
6583
6584
        let repr_packed = NonZeroUsize::new(2);
6585
6586
        let expected = DstLayout::new_zst(None)
6587
            .extend(DstLayout::for_type::<NotKnownLayout<AU32>>(), repr_packed)
6588
            .extend(<[u8] as KnownLayout>::LAYOUT, repr_packed)
6589
            .pad_to_align();
6590
6591
        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, expected);
6592
        assert_eq!(<KL10PackedN as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4));
6593
6594
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6595
        // |          Y |        N |              Y |        Y |      KL11 |
6596
        #[derive(KnownLayout)]
6597
        #[repr(C)]
6598
        struct KL11(NotKnownLayout<AU64>, u8);
6599
6600
        let expected = DstLayout::new_zst(None)
6601
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
6602
            .extend(<u8 as KnownLayout>::LAYOUT, None)
6603
            .pad_to_align();
6604
6605
        assert_eq!(<KL11 as KnownLayout>::LAYOUT, expected);
6606
        assert_eq!(<KL11 as KnownLayout>::LAYOUT, sized_layout(8, 16));
6607
6608
        // ...with `align(N)`:
6609
        #[derive(KnownLayout)]
6610
        #[repr(C, align(64))]
6611
        struct KL11Align(NotKnownLayout<AU64>, u8);
6612
6613
        let repr_align = NonZeroUsize::new(64);
6614
6615
        let expected = DstLayout::new_zst(repr_align)
6616
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), None)
6617
            .extend(<u8 as KnownLayout>::LAYOUT, None)
6618
            .pad_to_align();
6619
6620
        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, expected);
6621
        assert_eq!(<KL11Align as KnownLayout>::LAYOUT, sized_layout(64, 64));
6622
6623
        // ...with `packed`:
6624
        #[derive(KnownLayout)]
6625
        #[repr(C, packed)]
6626
        struct KL11Packed(NotKnownLayout<AU64>, u8);
6627
6628
        let repr_packed = NonZeroUsize::new(1);
6629
6630
        let expected = DstLayout::new_zst(None)
6631
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
6632
            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
6633
            .pad_to_align();
6634
6635
        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, expected);
6636
        assert_eq!(<KL11Packed as KnownLayout>::LAYOUT, sized_layout(1, 9));
6637
6638
        // ...with `packed(N)`:
6639
        #[derive(KnownLayout)]
6640
        #[repr(C, packed(2))]
6641
        struct KL11PackedN(NotKnownLayout<AU64>, u8);
6642
6643
        let repr_packed = NonZeroUsize::new(2);
6644
6645
        let expected = DstLayout::new_zst(None)
6646
            .extend(DstLayout::for_type::<NotKnownLayout<AU64>>(), repr_packed)
6647
            .extend(<u8 as KnownLayout>::LAYOUT, repr_packed)
6648
            .pad_to_align();
6649
6650
        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, expected);
6651
        assert_eq!(<KL11PackedN as KnownLayout>::LAYOUT, sized_layout(2, 10));
6652
6653
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6654
        // |          Y |        Y |              Y |        N |      KL14 |
6655
        #[derive(KnownLayout)]
6656
        #[repr(C)]
6657
        struct KL14<T: ?Sized + KnownLayout>(u8, T);
6658
6659
        fn _test_kl14<T: ?Sized + KnownLayout>(kl: &KL14<T>) {
6660
            _assert_kl(kl)
6661
        }
6662
6663
        // | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
6664
        // |          Y |        Y |              Y |        Y |      KL15 |
6665
        #[derive(KnownLayout)]
6666
        #[repr(C)]
6667
        struct KL15<T: KnownLayout>(u8, T);
6668
6669
        fn _test_kl15<T: KnownLayout>(t: T) -> impl KnownLayout {
6670
            let _ = KL15(0u8, t);
6671
        }
6672
6673
        // Test a variety of combinations of field types:
6674
        //  - ()
6675
        //  - u8
6676
        //  - AU16
6677
        //  - [()]
6678
        //  - [u8]
6679
        //  - [AU16]
6680
6681
        #[allow(clippy::upper_case_acronyms)]
6682
        #[derive(KnownLayout)]
6683
        #[repr(C)]
6684
        struct KLTU<T, U: ?Sized>(T, U);
6685
6686
        assert_eq!(<KLTU<(), ()> as KnownLayout>::LAYOUT, sized_layout(1, 0));
6687
6688
        assert_eq!(<KLTU<(), u8> as KnownLayout>::LAYOUT, sized_layout(1, 1));
6689
6690
        assert_eq!(<KLTU<(), AU16> as KnownLayout>::LAYOUT, sized_layout(2, 2));
6691
6692
        assert_eq!(<KLTU<(), [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 0));
6693
6694
        assert_eq!(<KLTU<(), [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0));
6695
6696
        assert_eq!(<KLTU<(), [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 0));
6697
6698
        assert_eq!(<KLTU<u8, ()> as KnownLayout>::LAYOUT, sized_layout(1, 1));
6699
6700
        assert_eq!(<KLTU<u8, u8> as KnownLayout>::LAYOUT, sized_layout(1, 2));
6701
6702
        assert_eq!(<KLTU<u8, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6703
6704
        assert_eq!(<KLTU<u8, [()]> as KnownLayout>::LAYOUT, unsized_layout(1, 0, 1));
6705
6706
        assert_eq!(<KLTU<u8, [u8]> as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1));
6707
6708
        assert_eq!(<KLTU<u8, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2));
6709
6710
        assert_eq!(<KLTU<AU16, ()> as KnownLayout>::LAYOUT, sized_layout(2, 2));
6711
6712
        assert_eq!(<KLTU<AU16, u8> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6713
6714
        assert_eq!(<KLTU<AU16, AU16> as KnownLayout>::LAYOUT, sized_layout(2, 4));
6715
6716
        assert_eq!(<KLTU<AU16, [()]> as KnownLayout>::LAYOUT, unsized_layout(2, 0, 2));
6717
6718
        assert_eq!(<KLTU<AU16, [u8]> as KnownLayout>::LAYOUT, unsized_layout(2, 1, 2));
6719
6720
        assert_eq!(<KLTU<AU16, [AU16]> as KnownLayout>::LAYOUT, unsized_layout(2, 2, 2));
6721
6722
        // Test a variety of field counts.
6723
6724
        #[derive(KnownLayout)]
6725
        #[repr(C)]
6726
        struct KLF0;
6727
6728
        assert_eq!(<KLF0 as KnownLayout>::LAYOUT, sized_layout(1, 0));
6729
6730
        #[derive(KnownLayout)]
6731
        #[repr(C)]
6732
        struct KLF1([u8]);
6733
6734
        assert_eq!(<KLF1 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 0));
6735
6736
        #[derive(KnownLayout)]
6737
        #[repr(C)]
6738
        struct KLF2(NotKnownLayout<u8>, [u8]);
6739
6740
        assert_eq!(<KLF2 as KnownLayout>::LAYOUT, unsized_layout(1, 1, 1));
6741
6742
        #[derive(KnownLayout)]
6743
        #[repr(C)]
6744
        struct KLF3(NotKnownLayout<u8>, NotKnownLayout<AU16>, [u8]);
6745
6746
        assert_eq!(<KLF3 as KnownLayout>::LAYOUT, unsized_layout(2, 1, 4));
6747
6748
        #[derive(KnownLayout)]
6749
        #[repr(C)]
6750
        struct KLF4(NotKnownLayout<u8>, NotKnownLayout<AU16>, NotKnownLayout<AU32>, [u8]);
6751
6752
        assert_eq!(<KLF4 as KnownLayout>::LAYOUT, unsized_layout(4, 1, 8));
6753
    }
6754
6755
    #[test]
6756
    fn test_object_safety() {
6757
        fn _takes_from_zeroes(_: &dyn FromZeroes) {}
6758
        fn _takes_from_bytes(_: &dyn FromBytes) {}
6759
        fn _takes_unaligned(_: &dyn Unaligned) {}
6760
    }
6761
6762
    #[test]
6763
    fn test_from_zeroes_only() {
6764
        // Test types that implement `FromZeroes` but not `FromBytes`.
6765
6766
        assert!(!bool::new_zeroed());
6767
        assert_eq!(char::new_zeroed(), '\0');
6768
6769
        #[cfg(feature = "alloc")]
6770
        {
6771
            assert_eq!(bool::new_box_zeroed(), Box::new(false));
6772
            assert_eq!(char::new_box_zeroed(), Box::new('\0'));
6773
6774
            assert_eq!(bool::new_box_slice_zeroed(3).as_ref(), [false, false, false]);
6775
            assert_eq!(char::new_box_slice_zeroed(3).as_ref(), ['\0', '\0', '\0']);
6776
6777
            assert_eq!(bool::new_vec_zeroed(3).as_ref(), [false, false, false]);
6778
            assert_eq!(char::new_vec_zeroed(3).as_ref(), ['\0', '\0', '\0']);
6779
        }
6780
6781
        let mut string = "hello".to_string();
6782
        let s: &mut str = string.as_mut();
6783
        assert_eq!(s, "hello");
6784
        s.zero();
6785
        assert_eq!(s, "\0\0\0\0\0");
6786
    }
6787
6788
    #[test]
6789
    fn test_read_write() {
6790
        const VAL: u64 = 0x12345678;
6791
        #[cfg(target_endian = "big")]
6792
        const VAL_BYTES: [u8; 8] = VAL.to_be_bytes();
6793
        #[cfg(target_endian = "little")]
6794
        const VAL_BYTES: [u8; 8] = VAL.to_le_bytes();
6795
6796
        // Test `FromBytes::{read_from, read_from_prefix, read_from_suffix}`.
6797
6798
        assert_eq!(u64::read_from(&VAL_BYTES[..]), Some(VAL));
6799
        // The first 8 bytes are from `VAL_BYTES` and the second 8 bytes are all
6800
        // zeroes.
6801
        let bytes_with_prefix: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
6802
        assert_eq!(u64::read_from_prefix(&bytes_with_prefix[..]), Some(VAL));
6803
        assert_eq!(u64::read_from_suffix(&bytes_with_prefix[..]), Some(0));
6804
        // The first 8 bytes are all zeroes and the second 8 bytes are from
6805
        // `VAL_BYTES`
6806
        let bytes_with_suffix: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
6807
        assert_eq!(u64::read_from_prefix(&bytes_with_suffix[..]), Some(0));
6808
        assert_eq!(u64::read_from_suffix(&bytes_with_suffix[..]), Some(VAL));
6809
6810
        // Test `AsBytes::{write_to, write_to_prefix, write_to_suffix}`.
6811
6812
        let mut bytes = [0u8; 8];
6813
        assert_eq!(VAL.write_to(&mut bytes[..]), Some(()));
6814
        assert_eq!(bytes, VAL_BYTES);
6815
        let mut bytes = [0u8; 16];
6816
        assert_eq!(VAL.write_to_prefix(&mut bytes[..]), Some(()));
6817
        let want: [u8; 16] = transmute!([VAL_BYTES, [0; 8]]);
6818
        assert_eq!(bytes, want);
6819
        let mut bytes = [0u8; 16];
6820
        assert_eq!(VAL.write_to_suffix(&mut bytes[..]), Some(()));
6821
        let want: [u8; 16] = transmute!([[0; 8], VAL_BYTES]);
6822
        assert_eq!(bytes, want);
6823
    }
6824
6825
    #[test]
6826
    fn test_transmute() {
6827
        // Test that memory is transmuted as expected.
6828
        let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6829
        let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6830
        let x: [[u8; 2]; 4] = transmute!(array_of_u8s);
6831
        assert_eq!(x, array_of_arrays);
6832
        let x: [u8; 8] = transmute!(array_of_arrays);
6833
        assert_eq!(x, array_of_u8s);
6834
6835
        // Test that the source expression's value is forgotten rather than
6836
        // dropped.
6837
        #[derive(AsBytes)]
6838
        #[repr(transparent)]
6839
        struct PanicOnDrop(());
6840
        impl Drop for PanicOnDrop {
6841
            fn drop(&mut self) {
6842
                panic!("PanicOnDrop::drop");
6843
            }
6844
        }
6845
        #[allow(clippy::let_unit_value)]
6846
        let _: () = transmute!(PanicOnDrop(()));
6847
6848
        // Test that `transmute!` is legal in a const context.
6849
        const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
6850
        const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
6851
        const X: [[u8; 2]; 4] = transmute!(ARRAY_OF_U8S);
6852
        assert_eq!(X, ARRAY_OF_ARRAYS);
6853
    }
6854
6855
    #[test]
6856
    fn test_transmute_ref() {
6857
        // Test that memory is transmuted as expected.
6858
        let array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6859
        let array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6860
        let x: &[[u8; 2]; 4] = transmute_ref!(&array_of_u8s);
6861
        assert_eq!(*x, array_of_arrays);
6862
        let x: &[u8; 8] = transmute_ref!(&array_of_arrays);
6863
        assert_eq!(*x, array_of_u8s);
6864
6865
        // Test that `transmute_ref!` is legal in a const context.
6866
        const ARRAY_OF_U8S: [u8; 8] = [0u8, 1, 2, 3, 4, 5, 6, 7];
6867
        const ARRAY_OF_ARRAYS: [[u8; 2]; 4] = [[0, 1], [2, 3], [4, 5], [6, 7]];
6868
        #[allow(clippy::redundant_static_lifetimes)]
6869
        const X: &'static [[u8; 2]; 4] = transmute_ref!(&ARRAY_OF_U8S);
6870
        assert_eq!(*X, ARRAY_OF_ARRAYS);
6871
6872
        // Test that it's legal to transmute a reference while shrinking the
6873
        // lifetime (note that `X` has the lifetime `'static`).
6874
        let x: &[u8; 8] = transmute_ref!(X);
6875
        assert_eq!(*x, ARRAY_OF_U8S);
6876
6877
        // Test that `transmute_ref!` supports decreasing alignment.
6878
        let u = AU64(0);
6879
        let array = [0, 0, 0, 0, 0, 0, 0, 0];
6880
        let x: &[u8; 8] = transmute_ref!(&u);
6881
        assert_eq!(*x, array);
6882
6883
        // Test that a mutable reference can be turned into an immutable one.
6884
        let mut x = 0u8;
6885
        #[allow(clippy::useless_transmute)]
6886
        let y: &u8 = transmute_ref!(&mut x);
6887
        assert_eq!(*y, 0);
6888
    }
6889
6890
    #[test]
6891
    fn test_transmute_mut() {
6892
        // Test that memory is transmuted as expected.
6893
        let mut array_of_u8s = [0u8, 1, 2, 3, 4, 5, 6, 7];
6894
        let mut array_of_arrays = [[0, 1], [2, 3], [4, 5], [6, 7]];
6895
        let x: &mut [[u8; 2]; 4] = transmute_mut!(&mut array_of_u8s);
6896
        assert_eq!(*x, array_of_arrays);
6897
        let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
6898
        assert_eq!(*x, array_of_u8s);
6899
6900
        {
6901
            // Test that it's legal to transmute a reference while shrinking the
6902
            // lifetime.
6903
            let x: &mut [u8; 8] = transmute_mut!(&mut array_of_arrays);
6904
            assert_eq!(*x, array_of_u8s);
6905
        }
6906
        // Test that `transmute_mut!` supports decreasing alignment.
6907
        let mut u = AU64(0);
6908
        let array = [0, 0, 0, 0, 0, 0, 0, 0];
6909
        let x: &[u8; 8] = transmute_mut!(&mut u);
6910
        assert_eq!(*x, array);
6911
6912
        // Test that a mutable reference can be turned into an immutable one.
6913
        let mut x = 0u8;
6914
        #[allow(clippy::useless_transmute)]
6915
        let y: &u8 = transmute_mut!(&mut x);
6916
        assert_eq!(*y, 0);
6917
    }
6918
6919
    #[test]
6920
    fn test_macros_evaluate_args_once() {
6921
        let mut ctr = 0;
6922
        let _: usize = transmute!({
6923
            ctr += 1;
6924
            0usize
6925
        });
6926
        assert_eq!(ctr, 1);
6927
6928
        let mut ctr = 0;
6929
        let _: &usize = transmute_ref!({
6930
            ctr += 1;
6931
            &0usize
6932
        });
6933
        assert_eq!(ctr, 1);
6934
    }
6935
6936
    #[test]
6937
    fn test_include_value() {
6938
        const AS_U32: u32 = include_value!("../testdata/include_value/data");
6939
        assert_eq!(AS_U32, u32::from_ne_bytes([b'a', b'b', b'c', b'd']));
6940
        const AS_I32: i32 = include_value!("../testdata/include_value/data");
6941
        assert_eq!(AS_I32, i32::from_ne_bytes([b'a', b'b', b'c', b'd']));
6942
    }
6943
6944
    #[test]
6945
    fn test_address() {
6946
        // Test that the `Deref` and `DerefMut` implementations return a
6947
        // reference which points to the right region of memory.
6948
6949
        let buf = [0];
6950
        let r = Ref::<_, u8>::new(&buf[..]).unwrap();
6951
        let buf_ptr = buf.as_ptr();
6952
        let deref_ptr: *const u8 = r.deref();
6953
        assert_eq!(buf_ptr, deref_ptr);
6954
6955
        let buf = [0];
6956
        let r = Ref::<_, [u8]>::new_slice(&buf[..]).unwrap();
6957
        let buf_ptr = buf.as_ptr();
6958
        let deref_ptr = r.deref().as_ptr();
6959
        assert_eq!(buf_ptr, deref_ptr);
6960
    }
6961
6962
    // Verify that values written to a `Ref` are properly shared between the
6963
    // typed and untyped representations, that reads via `deref` and `read`
6964
    // behave the same, and that writes via `deref_mut` and `write` behave the
6965
    // same.
6966
    fn test_new_helper(mut r: Ref<&mut [u8], AU64>) {
6967
        // assert that the value starts at 0
6968
        assert_eq!(*r, AU64(0));
6969
        assert_eq!(r.read(), AU64(0));
6970
6971
        // Assert that values written to the typed value are reflected in the
6972
        // byte slice.
6973
        const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
6974
        *r = VAL1;
6975
        assert_eq!(r.bytes(), &VAL1.to_bytes());
6976
        *r = AU64(0);
6977
        r.write(VAL1);
6978
        assert_eq!(r.bytes(), &VAL1.to_bytes());
6979
6980
        // Assert that values written to the byte slice are reflected in the
6981
        // typed value.
6982
        const VAL2: AU64 = AU64(!VAL1.0); // different from `VAL1`
6983
        r.bytes_mut().copy_from_slice(&VAL2.to_bytes()[..]);
6984
        assert_eq!(*r, VAL2);
6985
        assert_eq!(r.read(), VAL2);
6986
    }
6987
6988
    // Verify that values written to a `Ref` are properly shared between the
6989
    // typed and untyped representations; pass a value with `typed_len` `AU64`s
6990
    // backed by an array of `typed_len * 8` bytes.
6991
    fn test_new_helper_slice(mut r: Ref<&mut [u8], [AU64]>, typed_len: usize) {
6992
        // Assert that the value starts out zeroed.
6993
        assert_eq!(&*r, vec![AU64(0); typed_len].as_slice());
6994
6995
        // Check the backing storage is the exact same slice.
6996
        let untyped_len = typed_len * 8;
6997
        assert_eq!(r.bytes().len(), untyped_len);
6998
        assert_eq!(r.bytes().as_ptr(), r.as_ptr().cast::<u8>());
6999
7000
        // Assert that values written to the typed value are reflected in the
7001
        // byte slice.
7002
        const VAL1: AU64 = AU64(0xFF00FF00FF00FF00);
7003
        for typed in &mut *r {
7004
            *typed = VAL1;
7005
        }
7006
        assert_eq!(r.bytes(), VAL1.0.to_ne_bytes().repeat(typed_len).as_slice());
7007
7008
        // Assert that values written to the byte slice are reflected in the
7009
        // typed value.
7010
        const VAL2: AU64 = AU64(!VAL1.0); // different from VAL1
7011
        r.bytes_mut().copy_from_slice(&VAL2.0.to_ne_bytes().repeat(typed_len));
7012
        assert!(r.iter().copied().all(|x| x == VAL2));
7013
    }
7014
7015
    // Verify that values written to a `Ref` are properly shared between the
7016
    // typed and untyped representations, that reads via `deref` and `read`
7017
    // behave the same, and that writes via `deref_mut` and `write` behave the
7018
    // same.
7019
    fn test_new_helper_unaligned(mut r: Ref<&mut [u8], [u8; 8]>) {
7020
        // assert that the value starts at 0
7021
        assert_eq!(*r, [0; 8]);
7022
        assert_eq!(r.read(), [0; 8]);
7023
7024
        // Assert that values written to the typed value are reflected in the
7025
        // byte slice.
7026
        const VAL1: [u8; 8] = [0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00];
7027
        *r = VAL1;
7028
        assert_eq!(r.bytes(), &VAL1);
7029
        *r = [0; 8];
7030
        r.write(VAL1);
7031
        assert_eq!(r.bytes(), &VAL1);
7032
7033
        // Assert that values written to the byte slice are reflected in the
7034
        // typed value.
7035
        const VAL2: [u8; 8] = [0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF]; // different from VAL1
7036
        r.bytes_mut().copy_from_slice(&VAL2[..]);
7037
        assert_eq!(*r, VAL2);
7038
        assert_eq!(r.read(), VAL2);
7039
    }
7040
7041
    // Verify that values written to a `Ref` are properly shared between the
7042
    // typed and untyped representations; pass a value with `len` `u8`s backed
7043
    // by an array of `len` bytes.
7044
    fn test_new_helper_slice_unaligned(mut r: Ref<&mut [u8], [u8]>, len: usize) {
7045
        // Assert that the value starts out zeroed.
7046
        assert_eq!(&*r, vec![0u8; len].as_slice());
7047
7048
        // Check the backing storage is the exact same slice.
7049
        assert_eq!(r.bytes().len(), len);
7050
        assert_eq!(r.bytes().as_ptr(), r.as_ptr());
7051
7052
        // Assert that values written to the typed value are reflected in the
7053
        // byte slice.
7054
        let mut expected_bytes = [0xFF, 0x00].iter().copied().cycle().take(len).collect::<Vec<_>>();
7055
        r.copy_from_slice(&expected_bytes);
7056
        assert_eq!(r.bytes(), expected_bytes.as_slice());
7057
7058
        // Assert that values written to the byte slice are reflected in the
7059
        // typed value.
7060
        for byte in &mut expected_bytes {
7061
            *byte = !*byte; // different from `expected_len`
7062
        }
7063
        r.bytes_mut().copy_from_slice(&expected_bytes);
7064
        assert_eq!(&*r, expected_bytes.as_slice());
7065
    }
7066
7067
    #[test]
7068
    fn test_new_aligned_sized() {
7069
        // Test that a properly-aligned, properly-sized buffer works for new,
7070
        // new_from_prefix, and new_from_suffix, and that new_from_prefix and
7071
        // new_from_suffix return empty slices. Test that a properly-aligned
7072
        // buffer whose length is a multiple of the element size works for
7073
        // new_slice. Test that xxx_zeroed behaves the same, and zeroes the
7074
        // memory.
7075
7076
        // A buffer with an alignment of 8.
7077
        let mut buf = Align::<[u8; 8], AU64>::default();
7078
        // `buf.t` should be aligned to 8, so this should always succeed.
7079
        test_new_helper(Ref::<_, AU64>::new(&mut buf.t[..]).unwrap());
7080
        let ascending: [u8; 8] = (0..8).collect::<Vec<_>>().try_into().unwrap();
7081
        buf.t = ascending;
7082
        test_new_helper(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).unwrap());
7083
        {
7084
            // In a block so that `r` and `suffix` don't live too long.
7085
            buf.set_default();
7086
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix(&mut buf.t[..]).unwrap();
7087
            assert!(suffix.is_empty());
7088
            test_new_helper(r);
7089
        }
7090
        {
7091
            buf.t = ascending;
7092
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).unwrap();
7093
            assert!(suffix.is_empty());
7094
            test_new_helper(r);
7095
        }
7096
        {
7097
            buf.set_default();
7098
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix(&mut buf.t[..]).unwrap();
7099
            assert!(prefix.is_empty());
7100
            test_new_helper(r);
7101
        }
7102
        {
7103
            buf.t = ascending;
7104
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).unwrap();
7105
            assert!(prefix.is_empty());
7106
            test_new_helper(r);
7107
        }
7108
7109
        // A buffer with alignment 8 and length 24. We choose this length very
7110
        // intentionally: if we instead used length 16, then the prefix and
7111
        // suffix lengths would be identical. In the past, we used length 16,
7112
        // which resulted in this test failing to discover the bug uncovered in
7113
        // #506.
7114
        let mut buf = Align::<[u8; 24], AU64>::default();
7115
        // `buf.t` should be aligned to 8 and have a length which is a multiple
7116
        // of `size_of::<AU64>()`, so this should always succeed.
7117
        test_new_helper_slice(Ref::<_, [AU64]>::new_slice(&mut buf.t[..]).unwrap(), 3);
7118
        let ascending: [u8; 24] = (0..24).collect::<Vec<_>>().try_into().unwrap();
7119
        // 16 ascending bytes followed by 8 zeros.
7120
        let mut ascending_prefix = ascending;
7121
        ascending_prefix[16..].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
7122
        // 8 zeros followed by 16 ascending bytes.
7123
        let mut ascending_suffix = ascending;
7124
        ascending_suffix[..8].copy_from_slice(&[0, 0, 0, 0, 0, 0, 0, 0]);
7125
        test_new_helper_slice(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[..]).unwrap(), 3);
7126
7127
        {
7128
            buf.t = ascending_suffix;
7129
            let (r, suffix) = Ref::<_, [AU64]>::new_slice_from_prefix(&mut buf.t[..], 1).unwrap();
7130
            assert_eq!(suffix, &ascending[8..]);
7131
            test_new_helper_slice(r, 1);
7132
        }
7133
        {
7134
            buf.t = ascending_suffix;
7135
            let (r, suffix) =
7136
                Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], 1).unwrap();
7137
            assert_eq!(suffix, &ascending[8..]);
7138
            test_new_helper_slice(r, 1);
7139
        }
7140
        {
7141
            buf.t = ascending_prefix;
7142
            let (prefix, r) = Ref::<_, [AU64]>::new_slice_from_suffix(&mut buf.t[..], 1).unwrap();
7143
            assert_eq!(prefix, &ascending[..16]);
7144
            test_new_helper_slice(r, 1);
7145
        }
7146
        {
7147
            buf.t = ascending_prefix;
7148
            let (prefix, r) =
7149
                Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], 1).unwrap();
7150
            assert_eq!(prefix, &ascending[..16]);
7151
            test_new_helper_slice(r, 1);
7152
        }
7153
    }
7154
7155
    #[test]
7156
    fn test_new_unaligned_sized() {
7157
        // Test that an unaligned, properly-sized buffer works for
7158
        // `new_unaligned`, `new_unaligned_from_prefix`, and
7159
        // `new_unaligned_from_suffix`, and that `new_unaligned_from_prefix`
7160
        // `new_unaligned_from_suffix` return empty slices. Test that an
7161
        // unaligned buffer whose length is a multiple of the element size works
7162
        // for `new_slice`. Test that `xxx_zeroed` behaves the same, and zeroes
7163
        // the memory.
7164
7165
        let mut buf = [0u8; 8];
7166
        test_new_helper_unaligned(Ref::<_, [u8; 8]>::new_unaligned(&mut buf[..]).unwrap());
7167
        buf = [0xFFu8; 8];
7168
        test_new_helper_unaligned(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf[..]).unwrap());
7169
        {
7170
            // In a block so that `r` and `suffix` don't live too long.
7171
            buf = [0u8; 8];
7172
            let (r, suffix) = Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&mut buf[..]).unwrap();
7173
            assert!(suffix.is_empty());
7174
            test_new_helper_unaligned(r);
7175
        }
7176
        {
7177
            buf = [0xFFu8; 8];
7178
            let (r, suffix) =
7179
                Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf[..]).unwrap();
7180
            assert!(suffix.is_empty());
7181
            test_new_helper_unaligned(r);
7182
        }
7183
        {
7184
            buf = [0u8; 8];
7185
            let (prefix, r) = Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&mut buf[..]).unwrap();
7186
            assert!(prefix.is_empty());
7187
            test_new_helper_unaligned(r);
7188
        }
7189
        {
7190
            buf = [0xFFu8; 8];
7191
            let (prefix, r) =
7192
                Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf[..]).unwrap();
7193
            assert!(prefix.is_empty());
7194
            test_new_helper_unaligned(r);
7195
        }
7196
7197
        let mut buf = [0u8; 16];
7198
        // `buf.t` should be aligned to 8 and have a length which is a multiple
7199
        // of `size_of::AU64>()`, so this should always succeed.
7200
        test_new_helper_slice_unaligned(
7201
            Ref::<_, [u8]>::new_slice_unaligned(&mut buf[..]).unwrap(),
7202
            16,
7203
        );
7204
        buf = [0xFFu8; 16];
7205
        test_new_helper_slice_unaligned(
7206
            Ref::<_, [u8]>::new_slice_unaligned_zeroed(&mut buf[..]).unwrap(),
7207
            16,
7208
        );
7209
7210
        {
7211
            buf = [0u8; 16];
7212
            let (r, suffix) =
7213
                Ref::<_, [u8]>::new_slice_unaligned_from_prefix(&mut buf[..], 8).unwrap();
7214
            assert_eq!(suffix, [0; 8]);
7215
            test_new_helper_slice_unaligned(r, 8);
7216
        }
7217
        {
7218
            buf = [0xFFu8; 16];
7219
            let (r, suffix) =
7220
                Ref::<_, [u8]>::new_slice_unaligned_from_prefix_zeroed(&mut buf[..], 8).unwrap();
7221
            assert_eq!(suffix, [0xFF; 8]);
7222
            test_new_helper_slice_unaligned(r, 8);
7223
        }
7224
        {
7225
            buf = [0u8; 16];
7226
            let (prefix, r) =
7227
                Ref::<_, [u8]>::new_slice_unaligned_from_suffix(&mut buf[..], 8).unwrap();
7228
            assert_eq!(prefix, [0; 8]);
7229
            test_new_helper_slice_unaligned(r, 8);
7230
        }
7231
        {
7232
            buf = [0xFFu8; 16];
7233
            let (prefix, r) =
7234
                Ref::<_, [u8]>::new_slice_unaligned_from_suffix_zeroed(&mut buf[..], 8).unwrap();
7235
            assert_eq!(prefix, [0xFF; 8]);
7236
            test_new_helper_slice_unaligned(r, 8);
7237
        }
7238
    }
7239
7240
    #[test]
7241
    fn test_new_oversized() {
7242
        // Test that a properly-aligned, overly-sized buffer works for
7243
        // `new_from_prefix` and `new_from_suffix`, and that they return the
7244
        // remainder and prefix of the slice respectively. Test that
7245
        // `xxx_zeroed` behaves the same, and zeroes the memory.
7246
7247
        let mut buf = Align::<[u8; 16], AU64>::default();
7248
        {
7249
            // In a block so that `r` and `suffix` don't live too long. `buf.t`
7250
            // should be aligned to 8, so this should always succeed.
7251
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix(&mut buf.t[..]).unwrap();
7252
            assert_eq!(suffix.len(), 8);
7253
            test_new_helper(r);
7254
        }
7255
        {
7256
            buf.t = [0xFFu8; 16];
7257
            // `buf.t` should be aligned to 8, so this should always succeed.
7258
            let (r, suffix) = Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).unwrap();
7259
            // Assert that the suffix wasn't zeroed.
7260
            assert_eq!(suffix, &[0xFFu8; 8]);
7261
            test_new_helper(r);
7262
        }
7263
        {
7264
            buf.set_default();
7265
            // `buf.t` should be aligned to 8, so this should always succeed.
7266
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix(&mut buf.t[..]).unwrap();
7267
            assert_eq!(prefix.len(), 8);
7268
            test_new_helper(r);
7269
        }
7270
        {
7271
            buf.t = [0xFFu8; 16];
7272
            // `buf.t` should be aligned to 8, so this should always succeed.
7273
            let (prefix, r) = Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).unwrap();
7274
            // Assert that the prefix wasn't zeroed.
7275
            assert_eq!(prefix, &[0xFFu8; 8]);
7276
            test_new_helper(r);
7277
        }
7278
    }
7279
7280
    #[test]
7281
    fn test_new_unaligned_oversized() {
7282
        // Test than an unaligned, overly-sized buffer works for
7283
        // `new_unaligned_from_prefix` and `new_unaligned_from_suffix`, and that
7284
        // they return the remainder and prefix of the slice respectively. Test
7285
        // that `xxx_zeroed` behaves the same, and zeroes the memory.
7286
7287
        let mut buf = [0u8; 16];
7288
        {
7289
            // In a block so that `r` and `suffix` don't live too long.
7290
            let (r, suffix) = Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&mut buf[..]).unwrap();
7291
            assert_eq!(suffix.len(), 8);
7292
            test_new_helper_unaligned(r);
7293
        }
7294
        {
7295
            buf = [0xFFu8; 16];
7296
            let (r, suffix) =
7297
                Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf[..]).unwrap();
7298
            // Assert that the suffix wasn't zeroed.
7299
            assert_eq!(suffix, &[0xFF; 8]);
7300
            test_new_helper_unaligned(r);
7301
        }
7302
        {
7303
            buf = [0u8; 16];
7304
            let (prefix, r) = Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&mut buf[..]).unwrap();
7305
            assert_eq!(prefix.len(), 8);
7306
            test_new_helper_unaligned(r);
7307
        }
7308
        {
7309
            buf = [0xFFu8; 16];
7310
            let (prefix, r) =
7311
                Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf[..]).unwrap();
7312
            // Assert that the prefix wasn't zeroed.
7313
            assert_eq!(prefix, &[0xFF; 8]);
7314
            test_new_helper_unaligned(r);
7315
        }
7316
    }
7317
7318
    #[test]
7319
    fn test_ref_from_mut_from() {
7320
        // Test `FromBytes::{ref_from, mut_from}{,_prefix,_suffix}` success cases
7321
        // Exhaustive coverage for these methods is covered by the `Ref` tests above,
7322
        // which these helper methods defer to.
7323
7324
        let mut buf =
7325
            Align::<[u8; 16], AU64>::new([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
7326
7327
        assert_eq!(
7328
            AU64::ref_from(&buf.t[8..]).unwrap().0.to_ne_bytes(),
7329
            [8, 9, 10, 11, 12, 13, 14, 15]
7330
        );
7331
        let suffix = AU64::mut_from(&mut buf.t[8..]).unwrap();
7332
        suffix.0 = 0x0101010101010101;
7333
        // The `[u8:9]` is a non-half size of the full buffer, which would catch
7334
        // `from_prefix` having the same implementation as `from_suffix` (issues #506, #511).
7335
        assert_eq!(<[u8; 9]>::ref_from_suffix(&buf.t[..]).unwrap(), &[7u8, 1, 1, 1, 1, 1, 1, 1, 1]);
7336
        let suffix = AU64::mut_from_suffix(&mut buf.t[1..]).unwrap();
7337
        suffix.0 = 0x0202020202020202;
7338
        <[u8; 10]>::mut_from_suffix(&mut buf.t[..]).unwrap()[0] = 42;
7339
        assert_eq!(<[u8; 9]>::ref_from_prefix(&buf.t[..]).unwrap(), &[0, 1, 2, 3, 4, 5, 42, 7, 2]);
7340
        <[u8; 2]>::mut_from_prefix(&mut buf.t[..]).unwrap()[1] = 30;
7341
        assert_eq!(buf.t, [0, 30, 2, 3, 4, 5, 42, 7, 2, 2, 2, 2, 2, 2, 2, 2]);
7342
    }
7343
7344
    #[test]
7345
    fn test_ref_from_mut_from_error() {
7346
        // Test `FromBytes::{ref_from, mut_from}{,_prefix,_suffix}` error cases.
7347
7348
        // Fail because the buffer is too large.
7349
        let mut buf = Align::<[u8; 16], AU64>::default();
7350
        // `buf.t` should be aligned to 8, so only the length check should fail.
7351
        assert!(AU64::ref_from(&buf.t[..]).is_none());
7352
        assert!(AU64::mut_from(&mut buf.t[..]).is_none());
7353
        assert!(<[u8; 8]>::ref_from(&buf.t[..]).is_none());
7354
        assert!(<[u8; 8]>::mut_from(&mut buf.t[..]).is_none());
7355
7356
        // Fail because the buffer is too small.
7357
        let mut buf = Align::<[u8; 4], AU64>::default();
7358
        assert!(AU64::ref_from(&buf.t[..]).is_none());
7359
        assert!(AU64::mut_from(&mut buf.t[..]).is_none());
7360
        assert!(<[u8; 8]>::ref_from(&buf.t[..]).is_none());
7361
        assert!(<[u8; 8]>::mut_from(&mut buf.t[..]).is_none());
7362
        assert!(AU64::ref_from_prefix(&buf.t[..]).is_none());
7363
        assert!(AU64::mut_from_prefix(&mut buf.t[..]).is_none());
7364
        assert!(AU64::ref_from_suffix(&buf.t[..]).is_none());
7365
        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_none());
7366
        assert!(<[u8; 8]>::ref_from_prefix(&buf.t[..]).is_none());
7367
        assert!(<[u8; 8]>::mut_from_prefix(&mut buf.t[..]).is_none());
7368
        assert!(<[u8; 8]>::ref_from_suffix(&buf.t[..]).is_none());
7369
        assert!(<[u8; 8]>::mut_from_suffix(&mut buf.t[..]).is_none());
7370
7371
        // Fail because the alignment is insufficient.
7372
        let mut buf = Align::<[u8; 13], AU64>::default();
7373
        assert!(AU64::ref_from(&buf.t[1..]).is_none());
7374
        assert!(AU64::mut_from(&mut buf.t[1..]).is_none());
7375
        assert!(AU64::ref_from(&buf.t[1..]).is_none());
7376
        assert!(AU64::mut_from(&mut buf.t[1..]).is_none());
7377
        assert!(AU64::ref_from_prefix(&buf.t[1..]).is_none());
7378
        assert!(AU64::mut_from_prefix(&mut buf.t[1..]).is_none());
7379
        assert!(AU64::ref_from_suffix(&buf.t[..]).is_none());
7380
        assert!(AU64::mut_from_suffix(&mut buf.t[..]).is_none());
7381
    }
7382
7383
    #[test]
7384
    #[allow(clippy::cognitive_complexity)]
7385
    fn test_new_error() {
7386
        // Fail because the buffer is too large.
7387
7388
        // A buffer with an alignment of 8.
7389
        let mut buf = Align::<[u8; 16], AU64>::default();
7390
        // `buf.t` should be aligned to 8, so only the length check should fail.
7391
        assert!(Ref::<_, AU64>::new(&buf.t[..]).is_none());
7392
        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).is_none());
7393
        assert!(Ref::<_, [u8; 8]>::new_unaligned(&buf.t[..]).is_none());
7394
        assert!(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf.t[..]).is_none());
7395
7396
        // Fail because the buffer is too small.
7397
7398
        // A buffer with an alignment of 8.
7399
        let mut buf = Align::<[u8; 4], AU64>::default();
7400
        // `buf.t` should be aligned to 8, so only the length check should fail.
7401
        assert!(Ref::<_, AU64>::new(&buf.t[..]).is_none());
7402
        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[..]).is_none());
7403
        assert!(Ref::<_, [u8; 8]>::new_unaligned(&buf.t[..]).is_none());
7404
        assert!(Ref::<_, [u8; 8]>::new_unaligned_zeroed(&mut buf.t[..]).is_none());
7405
        assert!(Ref::<_, AU64>::new_from_prefix(&buf.t[..]).is_none());
7406
        assert!(Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[..]).is_none());
7407
        assert!(Ref::<_, AU64>::new_from_suffix(&buf.t[..]).is_none());
7408
        assert!(Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).is_none());
7409
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_prefix(&buf.t[..]).is_none());
7410
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_prefix_zeroed(&mut buf.t[..]).is_none());
7411
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_suffix(&buf.t[..]).is_none());
7412
        assert!(Ref::<_, [u8; 8]>::new_unaligned_from_suffix_zeroed(&mut buf.t[..]).is_none());
7413
7414
        // Fail because the length is not a multiple of the element size.
7415
7416
        let mut buf = Align::<[u8; 12], AU64>::default();
7417
        // `buf.t` has length 12, but element size is 8.
7418
        assert!(Ref::<_, [AU64]>::new_slice(&buf.t[..]).is_none());
7419
        assert!(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[..]).is_none());
7420
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned(&buf.t[..]).is_none());
7421
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_zeroed(&mut buf.t[..]).is_none());
7422
7423
        // Fail because the buffer is too short.
7424
        let mut buf = Align::<[u8; 12], AU64>::default();
7425
        // `buf.t` has length 12, but the element size is 8 (and we're expecting
7426
        // two of them).
7427
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[..], 2).is_none());
7428
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], 2).is_none());
7429
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[..], 2).is_none());
7430
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], 2).is_none());
7431
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix(&buf.t[..], 2).is_none());
7432
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix_zeroed(&mut buf.t[..], 2)
7433
            .is_none());
7434
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix(&buf.t[..], 2).is_none());
7435
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix_zeroed(&mut buf.t[..], 2)
7436
            .is_none());
7437
7438
        // Fail because the alignment is insufficient.
7439
7440
        // A buffer with an alignment of 8. An odd buffer size is chosen so that
7441
        // the last byte of the buffer has odd alignment.
7442
        let mut buf = Align::<[u8; 13], AU64>::default();
7443
        // Slicing from 1, we get a buffer with size 12 (so the length check
7444
        // should succeed) but an alignment of only 1, which is insufficient.
7445
        assert!(Ref::<_, AU64>::new(&buf.t[1..]).is_none());
7446
        assert!(Ref::<_, AU64>::new_zeroed(&mut buf.t[1..]).is_none());
7447
        assert!(Ref::<_, AU64>::new_from_prefix(&buf.t[1..]).is_none());
7448
        assert!(Ref::<_, AU64>::new_from_prefix_zeroed(&mut buf.t[1..]).is_none());
7449
        assert!(Ref::<_, [AU64]>::new_slice(&buf.t[1..]).is_none());
7450
        assert!(Ref::<_, [AU64]>::new_slice_zeroed(&mut buf.t[1..]).is_none());
7451
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[1..], 1).is_none());
7452
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[1..], 1).is_none());
7453
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[1..], 1).is_none());
7454
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[1..], 1).is_none());
7455
        // Slicing is unnecessary here because `new_from_suffix[_zeroed]` use
7456
        // the suffix of the slice, which has odd alignment.
7457
        assert!(Ref::<_, AU64>::new_from_suffix(&buf.t[..]).is_none());
7458
        assert!(Ref::<_, AU64>::new_from_suffix_zeroed(&mut buf.t[..]).is_none());
7459
7460
        // Fail due to arithmetic overflow.
7461
7462
        let mut buf = Align::<[u8; 16], AU64>::default();
7463
        let unreasonable_len = usize::MAX / mem::size_of::<AU64>() + 1;
7464
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix(&buf.t[..], unreasonable_len).is_none());
7465
        assert!(Ref::<_, [AU64]>::new_slice_from_prefix_zeroed(&mut buf.t[..], unreasonable_len)
7466
            .is_none());
7467
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix(&buf.t[..], unreasonable_len).is_none());
7468
        assert!(Ref::<_, [AU64]>::new_slice_from_suffix_zeroed(&mut buf.t[..], unreasonable_len)
7469
            .is_none());
7470
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix(&buf.t[..], unreasonable_len)
7471
            .is_none());
7472
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_prefix_zeroed(
7473
            &mut buf.t[..],
7474
            unreasonable_len
7475
        )
7476
        .is_none());
7477
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix(&buf.t[..], unreasonable_len)
7478
            .is_none());
7479
        assert!(Ref::<_, [[u8; 8]]>::new_slice_unaligned_from_suffix_zeroed(
7480
            &mut buf.t[..],
7481
            unreasonable_len
7482
        )
7483
        .is_none());
7484
    }
7485
7486
    // Tests for ensuring that, if a ZST is passed into a slice-like function,
7487
    // we always panic. Since these tests need to be separate per-function, and
7488
    // they tend to take up a lot of space, we generate them using a macro in a
7489
    // submodule instead. The submodule ensures that we can just re-use the name
7490
    // of the function under test for the name of the test itself.
7491
    mod test_zst_panics {
7492
        macro_rules! zst_test {
7493
            ($name:ident($($tt:tt)*), $constructor_in_panic_msg:tt) => {
7494
                #[test]
7495
                #[should_panic = concat!("Ref::", $constructor_in_panic_msg, " called on a zero-sized type")]
7496
                fn $name() {
7497
                    let mut buffer = [0u8];
7498
                    let r = $crate::Ref::<_, [()]>::$name(&mut buffer[..], $($tt)*);
7499
                    unreachable!("should have panicked, got {:?}", r);
7500
                }
7501
            }
7502
        }
7503
        zst_test!(new_slice(), "new_slice");
7504
        zst_test!(new_slice_zeroed(), "new_slice");
7505
        zst_test!(new_slice_from_prefix(1), "new_slice");
7506
        zst_test!(new_slice_from_prefix_zeroed(1), "new_slice");
7507
        zst_test!(new_slice_from_suffix(1), "new_slice");
7508
        zst_test!(new_slice_from_suffix_zeroed(1), "new_slice");
7509
        zst_test!(new_slice_unaligned(), "new_slice_unaligned");
7510
        zst_test!(new_slice_unaligned_zeroed(), "new_slice_unaligned");
7511
        zst_test!(new_slice_unaligned_from_prefix(1), "new_slice_unaligned");
7512
        zst_test!(new_slice_unaligned_from_prefix_zeroed(1), "new_slice_unaligned");
7513
        zst_test!(new_slice_unaligned_from_suffix(1), "new_slice_unaligned");
7514
        zst_test!(new_slice_unaligned_from_suffix_zeroed(1), "new_slice_unaligned");
7515
    }
7516
7517
    #[test]
7518
    fn test_as_bytes_methods() {
7519
        /// Run a series of tests by calling `AsBytes` methods on `t`.
7520
        ///
7521
        /// `bytes` is the expected byte sequence returned from `t.as_bytes()`
7522
        /// before `t` has been modified. `post_mutation` is the expected
7523
        /// sequence returned from `t.as_bytes()` after `t.as_bytes_mut()[0]`
7524
        /// has had its bits flipped (by applying `^= 0xFF`).
7525
        ///
7526
        /// `N` is the size of `t` in bytes.
7527
        fn test<T: FromBytes + AsBytes + Debug + Eq + ?Sized, const N: usize>(
7528
            t: &mut T,
7529
            bytes: &[u8],
7530
            post_mutation: &T,
7531
        ) {
7532
            // Test that we can access the underlying bytes, and that we get the
7533
            // right bytes and the right number of bytes.
7534
            assert_eq!(t.as_bytes(), bytes);
7535
7536
            // Test that changes to the underlying byte slices are reflected in
7537
            // the original object.
7538
            t.as_bytes_mut()[0] ^= 0xFF;
7539
            assert_eq!(t, post_mutation);
7540
            t.as_bytes_mut()[0] ^= 0xFF;
7541
7542
            // `write_to` rejects slices that are too small or too large.
7543
            assert_eq!(t.write_to(&mut vec![0; N - 1][..]), None);
7544
            assert_eq!(t.write_to(&mut vec![0; N + 1][..]), None);
7545
7546
            // `write_to` works as expected.
7547
            let mut bytes = [0; N];
7548
            assert_eq!(t.write_to(&mut bytes[..]), Some(()));
7549
            assert_eq!(bytes, t.as_bytes());
7550
7551
            // `write_to_prefix` rejects slices that are too small.
7552
            assert_eq!(t.write_to_prefix(&mut vec![0; N - 1][..]), None);
7553
7554
            // `write_to_prefix` works with exact-sized slices.
7555
            let mut bytes = [0; N];
7556
            assert_eq!(t.write_to_prefix(&mut bytes[..]), Some(()));
7557
            assert_eq!(bytes, t.as_bytes());
7558
7559
            // `write_to_prefix` works with too-large slices, and any bytes past
7560
            // the prefix aren't modified.
7561
            let mut too_many_bytes = vec![0; N + 1];
7562
            too_many_bytes[N] = 123;
7563
            assert_eq!(t.write_to_prefix(&mut too_many_bytes[..]), Some(()));
7564
            assert_eq!(&too_many_bytes[..N], t.as_bytes());
7565
            assert_eq!(too_many_bytes[N], 123);
7566
7567
            // `write_to_suffix` rejects slices that are too small.
7568
            assert_eq!(t.write_to_suffix(&mut vec![0; N - 1][..]), None);
7569
7570
            // `write_to_suffix` works with exact-sized slices.
7571
            let mut bytes = [0; N];
7572
            assert_eq!(t.write_to_suffix(&mut bytes[..]), Some(()));
7573
            assert_eq!(bytes, t.as_bytes());
7574
7575
            // `write_to_suffix` works with too-large slices, and any bytes
7576
            // before the suffix aren't modified.
7577
            let mut too_many_bytes = vec![0; N + 1];
7578
            too_many_bytes[0] = 123;
7579
            assert_eq!(t.write_to_suffix(&mut too_many_bytes[..]), Some(()));
7580
            assert_eq!(&too_many_bytes[1..], t.as_bytes());
7581
            assert_eq!(too_many_bytes[0], 123);
7582
        }
7583
7584
        #[derive(Debug, Eq, PartialEq, FromZeroes, FromBytes, AsBytes)]
7585
        #[repr(C)]
7586
        struct Foo {
7587
            a: u32,
7588
            b: Wrapping<u32>,
7589
            c: Option<NonZeroU32>,
7590
        }
7591
7592
        let expected_bytes: Vec<u8> = if cfg!(target_endian = "little") {
7593
            vec![1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0]
7594
        } else {
7595
            vec![0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0]
7596
        };
7597
        let post_mutation_expected_a =
7598
            if cfg!(target_endian = "little") { 0x00_00_00_FE } else { 0xFF_00_00_01 };
7599
        test::<_, 12>(
7600
            &mut Foo { a: 1, b: Wrapping(2), c: None },
7601
            expected_bytes.as_bytes(),
7602
            &Foo { a: post_mutation_expected_a, b: Wrapping(2), c: None },
7603
        );
7604
        test::<_, 3>(
7605
            Unsized::from_mut_slice(&mut [1, 2, 3]),
7606
            &[1, 2, 3],
7607
            Unsized::from_mut_slice(&mut [0xFE, 2, 3]),
7608
        );
7609
    }
7610
7611
    #[test]
7612
    fn test_array() {
7613
        #[derive(FromZeroes, FromBytes, AsBytes)]
7614
        #[repr(C)]
7615
        struct Foo {
7616
            a: [u16; 33],
7617
        }
7618
7619
        let foo = Foo { a: [0xFFFF; 33] };
7620
        let expected = [0xFFu8; 66];
7621
        assert_eq!(foo.as_bytes(), &expected[..]);
7622
    }
7623
7624
    #[test]
7625
    fn test_display_debug() {
7626
        let buf = Align::<[u8; 8], u64>::default();
7627
        let r = Ref::<_, u64>::new(&buf.t[..]).unwrap();
7628
        assert_eq!(format!("{}", r), "0");
7629
        assert_eq!(format!("{:?}", r), "Ref(0)");
7630
7631
        let buf = Align::<[u8; 8], u64>::default();
7632
        let r = Ref::<_, [u64]>::new_slice(&buf.t[..]).unwrap();
7633
        assert_eq!(format!("{:?}", r), "Ref([0])");
7634
    }
7635
7636
    #[test]
7637
    fn test_eq() {
7638
        let buf1 = 0_u64;
7639
        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7640
        let buf2 = 0_u64;
7641
        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7642
        assert_eq!(r1, r2);
7643
    }
7644
7645
    #[test]
7646
    fn test_ne() {
7647
        let buf1 = 0_u64;
7648
        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7649
        let buf2 = 1_u64;
7650
        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7651
        assert_ne!(r1, r2);
7652
    }
7653
7654
    #[test]
7655
    fn test_ord() {
7656
        let buf1 = 0_u64;
7657
        let r1 = Ref::<_, u64>::new(buf1.as_bytes()).unwrap();
7658
        let buf2 = 1_u64;
7659
        let r2 = Ref::<_, u64>::new(buf2.as_bytes()).unwrap();
7660
        assert!(r1 < r2);
7661
    }
7662
7663
    #[test]
7664
    fn test_new_zeroed() {
7665
        assert!(!bool::new_zeroed());
7666
        assert_eq!(u64::new_zeroed(), 0);
7667
        // This test exists in order to exercise unsafe code, especially when
7668
        // running under Miri.
7669
        #[allow(clippy::unit_cmp)]
7670
        {
7671
            assert_eq!(<()>::new_zeroed(), ());
7672
        }
7673
    }
7674
7675
    #[test]
7676
    fn test_transparent_packed_generic_struct() {
7677
        #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
7678
        #[repr(transparent)]
7679
        #[allow(dead_code)] // for the unused fields
7680
        struct Foo<T> {
7681
            _t: T,
7682
            _phantom: PhantomData<()>,
7683
        }
7684
7685
        assert_impl_all!(Foo<u32>: FromZeroes, FromBytes, AsBytes);
7686
        assert_impl_all!(Foo<u8>: Unaligned);
7687
7688
        #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
7689
        #[repr(packed)]
7690
        #[allow(dead_code)] // for the unused fields
7691
        struct Bar<T, U> {
7692
            _t: T,
7693
            _u: U,
7694
        }
7695
7696
        assert_impl_all!(Bar<u8, AU64>: FromZeroes, FromBytes, AsBytes, Unaligned);
7697
    }
7698
7699
    #[test]
7700
    fn test_impls() {
7701
        use core::borrow::Borrow;
7702
7703
        // A type that can supply test cases for testing
7704
        // `TryFromBytes::is_bit_valid`. All types passed to `assert_impls!`
7705
        // must implement this trait; that macro uses it to generate runtime
7706
        // tests for `TryFromBytes` impls.
7707
        //
7708
        // All `T: FromBytes` types are provided with a blanket impl. Other
7709
        // types must implement `TryFromBytesTestable` directly (ie using
7710
        // `impl_try_from_bytes_testable!`).
7711
        trait TryFromBytesTestable {
7712
            fn with_passing_test_cases<F: Fn(&Self)>(f: F);
7713
            fn with_failing_test_cases<F: Fn(&[u8])>(f: F);
7714
        }
7715
7716
        impl<T: FromBytes> TryFromBytesTestable for T {
7717
            fn with_passing_test_cases<F: Fn(&Self)>(f: F) {
7718
                // Test with a zeroed value.
7719
                f(&Self::new_zeroed());
7720
7721
                let ffs = {
7722
                    let mut t = Self::new_zeroed();
7723
                    let ptr: *mut T = &mut t;
7724
                    // SAFETY: `T: FromBytes`
7725
                    unsafe { ptr::write_bytes(ptr.cast::<u8>(), 0xFF, mem::size_of::<T>()) };
7726
                    t
7727
                };
7728
7729
                // Test with a value initialized with 0xFF.
7730
                f(&ffs);
7731
            }
7732
7733
            fn with_failing_test_cases<F: Fn(&[u8])>(_f: F) {}
7734
        }
7735
7736
        // Implements `TryFromBytesTestable`.
7737
        macro_rules! impl_try_from_bytes_testable {
7738
            // Base case for recursion (when the list of types has run out).
7739
            (=> @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {};
7740
            // Implements for type(s) with no type parameters.
7741
            ($ty:ty $(,$tys:ty)* => @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {
7742
                impl TryFromBytesTestable for $ty {
7743
                    impl_try_from_bytes_testable!(
7744
                        @methods     @success $($success_case),*
7745
                                 $(, @failure $($failure_case),*)?
7746
                    );
7747
                }
7748
                impl_try_from_bytes_testable!($($tys),* => @success $($success_case),* $(, @failure $($failure_case),*)?);
7749
            };
7750
            // Implements for multiple types with no type parameters.
7751
            ($($($ty:ty),* => @success $($success_case:expr), * $(, @failure $($failure_case:expr),*)?;)*) => {
7752
                $(
7753
                    impl_try_from_bytes_testable!($($ty),* => @success $($success_case),* $(, @failure $($failure_case),*)*);
7754
                )*
7755
            };
7756
            // Implements only the methods; caller must invoke this from inside
7757
            // an impl block.
7758
            (@methods @success $($success_case:expr),* $(, @failure $($failure_case:expr),*)?) => {
7759
                fn with_passing_test_cases<F: Fn(&Self)>(_f: F) {
7760
                    $(
7761
                        _f($success_case.borrow());
7762
                    )*
7763
                }
7764
7765
                fn with_failing_test_cases<F: Fn(&[u8])>(_f: F) {
7766
                    $($(
7767
                        // `unused_qualifications` is spuriously triggered on
7768
                        // `Option::<Self>::None`.
7769
                        #[allow(unused_qualifications)]
7770
                        let case = $failure_case.as_bytes();
7771
                        _f(case.as_bytes());
7772
                    )*)?
7773
                }
7774
            };
7775
        }
7776
7777
        // Note that these impls are only for types which are not `FromBytes`.
7778
        // `FromBytes` types are covered by a preceding blanket impl.
7779
        impl_try_from_bytes_testable!(
7780
            bool => @success true, false,
7781
                    @failure 2u8, 3u8, 0xFFu8;
7782
            char => @success '\u{0}', '\u{D7FF}', '\u{E000}', '\u{10FFFF}',
7783
                    @failure 0xD800u32, 0xDFFFu32, 0x110000u32;
7784
            str  => @success "", "hello", "❤️🧡💛💚💙💜",
7785
                    @failure [0, 159, 146, 150];
7786
            [u8] => @success [], [0, 1, 2];
7787
            NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32,
7788
            NonZeroI32, NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128,
7789
            NonZeroUsize, NonZeroIsize
7790
                 => @success Self::new(1).unwrap(),
7791
                    // Doing this instead of `0` ensures that we always satisfy
7792
                    // the size and alignment requirements of `Self` (whereas
7793
                    // `0` may be any integer type with a different size or
7794
                    // alignment than some `NonZeroXxx` types).
7795
                    @failure Option::<Self>::None;
7796
            [bool]
7797
                => @success [true, false], [false, true],
7798
                    @failure [2u8], [3u8], [0xFFu8], [0u8, 1u8, 2u8];
7799
        );
7800
7801
        // Asserts that `$ty` implements any `$trait` and doesn't implement any
7802
        // `!$trait`. Note that all `$trait`s must come before any `!$trait`s.
7803
        //
7804
        // For `T: TryFromBytes`, uses `TryFromBytesTestable` to test success
7805
        // and failure cases for `TryFromBytes::is_bit_valid`.
7806
        macro_rules! assert_impls {
7807
            ($ty:ty: TryFromBytes) => {
7808
                <$ty as TryFromBytesTestable>::with_passing_test_cases(|val| {
7809
                    let c = Ptr::from(val);
7810
                    // SAFETY:
7811
                    // - Since `val` is a normal reference, `c` is guranteed to
7812
                    //   be aligned, to point to a single allocation, and to
7813
                    //   have a size which doesn't overflow `isize`.
7814
                    // - Since `val` is a valid `$ty`, `c`'s referent satisfies
7815
                    //   the bit validity constraints of `is_bit_valid`, which
7816
                    //   are a superset of the bit validity constraints of
7817
                    //   `$ty`.
7818
                    let res = unsafe { <$ty as TryFromBytes>::is_bit_valid(c) };
7819
                    assert!(res, "{}::is_bit_valid({:?}): got false, expected true", stringify!($ty), val);
7820
7821
                    // TODO(#5): In addition to testing `is_bit_valid`, test the
7822
                    // methods built on top of it. This would both allow us to
7823
                    // test their implementations and actually convert the bytes
7824
                    // to `$ty`, giving Miri a chance to catch if this is
7825
                    // unsound (ie, if our `is_bit_valid` impl is buggy).
7826
                    //
7827
                    // The following code was tried, but it doesn't work because
7828
                    // a) some types are not `AsBytes` and, b) some types are
7829
                    // not `Sized`.
7830
                    //
7831
                    //   let r = <$ty as TryFromBytes>::try_from_ref(val.as_bytes()).unwrap();
7832
                    //   assert_eq!(r, &val);
7833
                    //   let r = <$ty as TryFromBytes>::try_from_mut(val.as_bytes_mut()).unwrap();
7834
                    //   assert_eq!(r, &mut val);
7835
                    //   let v = <$ty as TryFromBytes>::try_read_from(val.as_bytes()).unwrap();
7836
                    //   assert_eq!(v, val);
7837
                });
7838
                #[allow(clippy::as_conversions)]
7839
                <$ty as TryFromBytesTestable>::with_failing_test_cases(|c| {
7840
                    let res = <$ty as TryFromBytes>::try_from_ref(c);
7841
                    assert!(res.is_none(), "{}::is_bit_valid({:?}): got true, expected false", stringify!($ty), c);
7842
                });
7843
7844
                #[allow(dead_code)]
7845
                const _: () = { static_assertions::assert_impl_all!($ty: TryFromBytes); };
7846
            };
7847
            ($ty:ty: $trait:ident) => {
7848
                #[allow(dead_code)]
7849
                const _: () = { static_assertions::assert_impl_all!($ty: $trait); };
7850
            };
7851
            ($ty:ty: !$trait:ident) => {
7852
                #[allow(dead_code)]
7853
                const _: () = { static_assertions::assert_not_impl_any!($ty: $trait); };
7854
            };
7855
            ($ty:ty: $($trait:ident),* $(,)? $(!$negative_trait:ident),*) => {
7856
                $(
7857
                    assert_impls!($ty: $trait);
7858
                )*
7859
7860
                $(
7861
                    assert_impls!($ty: !$negative_trait);
7862
                )*
7863
            };
7864
        }
7865
7866
        // NOTE: The negative impl assertions here are not necessarily
7867
        // prescriptive. They merely serve as change detectors to make sure
7868
        // we're aware of what trait impls are getting added with a given
7869
        // change. Of course, some impls would be invalid (e.g., `bool:
7870
        // FromBytes`), and so this change detection is very important.
7871
7872
        assert_impls!((): KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7873
        assert_impls!(u8: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7874
        assert_impls!(i8: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7875
        assert_impls!(u16: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7876
        assert_impls!(i16: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7877
        assert_impls!(u32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7878
        assert_impls!(i32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7879
        assert_impls!(u64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7880
        assert_impls!(i64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7881
        assert_impls!(u128: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7882
        assert_impls!(i128: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7883
        assert_impls!(usize: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7884
        assert_impls!(isize: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7885
        assert_impls!(f32: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7886
        assert_impls!(f64: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7887
7888
        assert_impls!(bool: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7889
        assert_impls!(char: KnownLayout, TryFromBytes, FromZeroes, AsBytes, !FromBytes, !Unaligned);
7890
        assert_impls!(str: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7891
7892
        assert_impls!(NonZeroU8: KnownLayout, TryFromBytes, AsBytes, Unaligned, !FromZeroes, !FromBytes);
7893
        assert_impls!(NonZeroI8: KnownLayout, TryFromBytes, AsBytes, Unaligned, !FromZeroes, !FromBytes);
7894
        assert_impls!(NonZeroU16: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7895
        assert_impls!(NonZeroI16: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7896
        assert_impls!(NonZeroU32: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7897
        assert_impls!(NonZeroI32: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7898
        assert_impls!(NonZeroU64: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7899
        assert_impls!(NonZeroI64: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7900
        assert_impls!(NonZeroU128: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7901
        assert_impls!(NonZeroI128: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7902
        assert_impls!(NonZeroUsize: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7903
        assert_impls!(NonZeroIsize: KnownLayout, TryFromBytes, AsBytes, !FromBytes, !Unaligned);
7904
7905
        assert_impls!(Option<NonZeroU8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7906
        assert_impls!(Option<NonZeroI8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7907
        assert_impls!(Option<NonZeroU16>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7908
        assert_impls!(Option<NonZeroI16>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7909
        assert_impls!(Option<NonZeroU32>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7910
        assert_impls!(Option<NonZeroI32>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7911
        assert_impls!(Option<NonZeroU64>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7912
        assert_impls!(Option<NonZeroI64>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7913
        assert_impls!(Option<NonZeroU128>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7914
        assert_impls!(Option<NonZeroI128>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7915
        assert_impls!(Option<NonZeroUsize>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7916
        assert_impls!(Option<NonZeroIsize>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned);
7917
7918
        // Implements none of the ZC traits.
7919
        struct NotZerocopy;
7920
7921
        #[rustfmt::skip]
7922
        type FnManyArgs = fn(
7923
            NotZerocopy, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
7924
        ) -> (NotZerocopy, NotZerocopy);
7925
7926
        // Allowed, because we're not actually using this type for FFI.
7927
        #[allow(improper_ctypes_definitions)]
7928
        #[rustfmt::skip]
7929
        type ECFnManyArgs = extern "C" fn(
7930
            NotZerocopy, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
7931
        ) -> (NotZerocopy, NotZerocopy);
7932
7933
        #[cfg(feature = "alloc")]
7934
        assert_impls!(Option<Box<UnsafeCell<NotZerocopy>>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7935
        assert_impls!(Option<Box<[UnsafeCell<NotZerocopy>]>>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7936
        assert_impls!(Option<&'static UnsafeCell<NotZerocopy>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7937
        assert_impls!(Option<&'static [UnsafeCell<NotZerocopy>]>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7938
        assert_impls!(Option<&'static mut UnsafeCell<NotZerocopy>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7939
        assert_impls!(Option<&'static mut [UnsafeCell<NotZerocopy>]>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7940
        assert_impls!(Option<NonNull<UnsafeCell<NotZerocopy>>>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7941
        assert_impls!(Option<NonNull<[UnsafeCell<NotZerocopy>]>>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7942
        assert_impls!(Option<fn()>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7943
        assert_impls!(Option<FnManyArgs>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7944
        assert_impls!(Option<extern "C" fn()>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7945
        assert_impls!(Option<ECFnManyArgs>: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7946
7947
        assert_impls!(PhantomData<NotZerocopy>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7948
        assert_impls!(PhantomData<[u8]>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7949
7950
        assert_impls!(ManuallyDrop<u8>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7951
        assert_impls!(ManuallyDrop<[u8]>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7952
        assert_impls!(ManuallyDrop<NotZerocopy>: !TryFromBytes, !KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7953
        assert_impls!(ManuallyDrop<[NotZerocopy]>: !TryFromBytes, !KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7954
7955
        assert_impls!(MaybeUninit<u8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, Unaligned, !AsBytes);
7956
        assert_impls!(MaybeUninit<NotZerocopy>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7957
7958
        assert_impls!(Wrapping<u8>: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7959
        assert_impls!(Wrapping<NotZerocopy>: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7960
7961
        assert_impls!(Unalign<u8>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7962
        assert_impls!(Unalign<NotZerocopy>: Unaligned, !KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes);
7963
7964
        assert_impls!([u8]: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, Unaligned);
7965
        assert_impls!([bool]: KnownLayout, TryFromBytes, FromZeroes, AsBytes, Unaligned, !FromBytes);
7966
        assert_impls!([NotZerocopy]: !KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7967
        assert_impls!([u8; 0]: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7968
        assert_impls!([NotZerocopy; 0]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7969
        assert_impls!([u8; 1]: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned, !TryFromBytes);
7970
        assert_impls!([NotZerocopy; 1]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7971
7972
        assert_impls!(*const NotZerocopy: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7973
        assert_impls!(*mut NotZerocopy: KnownLayout, FromZeroes, !TryFromBytes, !FromBytes, !AsBytes, !Unaligned);
7974
        assert_impls!(*const [NotZerocopy]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7975
        assert_impls!(*mut [NotZerocopy]: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7976
        assert_impls!(*const dyn Debug: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7977
        assert_impls!(*mut dyn Debug: KnownLayout, !TryFromBytes, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
7978
7979
        #[cfg(feature = "simd")]
7980
        {
7981
            #[allow(unused_macros)]
7982
            macro_rules! test_simd_arch_mod {
7983
                ($arch:ident, $($typ:ident),*) => {
7984
                    {
7985
                        use core::arch::$arch::{$($typ),*};
7986
                        use crate::*;
7987
                        $( assert_impls!($typ: KnownLayout, TryFromBytes, FromZeroes, FromBytes, AsBytes, !Unaligned); )*
7988
                    }
7989
                };
7990
            }
7991
            #[cfg(target_arch = "x86")]
7992
            test_simd_arch_mod!(x86, __m128, __m128d, __m128i, __m256, __m256d, __m256i);
7993
7994
            #[cfg(all(feature = "simd-nightly", target_arch = "x86"))]
7995
            test_simd_arch_mod!(x86, __m512bh, __m512, __m512d, __m512i);
7996
7997
            #[cfg(target_arch = "x86_64")]
7998
            test_simd_arch_mod!(x86_64, __m128, __m128d, __m128i, __m256, __m256d, __m256i);
7999
8000
            #[cfg(all(feature = "simd-nightly", target_arch = "x86_64"))]
8001
            test_simd_arch_mod!(x86_64, __m512bh, __m512, __m512d, __m512i);
8002
8003
            #[cfg(target_arch = "wasm32")]
8004
            test_simd_arch_mod!(wasm32, v128);
8005
8006
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc"))]
8007
            test_simd_arch_mod!(
8008
                powerpc,
8009
                vector_bool_long,
8010
                vector_double,
8011
                vector_signed_long,
8012
                vector_unsigned_long
8013
            );
8014
8015
            #[cfg(all(feature = "simd-nightly", target_arch = "powerpc64"))]
8016
            test_simd_arch_mod!(
8017
                powerpc64,
8018
                vector_bool_long,
8019
                vector_double,
8020
                vector_signed_long,
8021
                vector_unsigned_long
8022
            );
8023
            #[cfg(target_arch = "aarch64")]
8024
            #[rustfmt::skip]
8025
            test_simd_arch_mod!(
8026
                aarch64, float32x2_t, float32x4_t, float64x1_t, float64x2_t, int8x8_t, int8x8x2_t,
8027
                int8x8x3_t, int8x8x4_t, int8x16_t, int8x16x2_t, int8x16x3_t, int8x16x4_t, int16x4_t,
8028
                int16x8_t, int32x2_t, int32x4_t, int64x1_t, int64x2_t, poly8x8_t, poly8x8x2_t, poly8x8x3_t,
8029
                poly8x8x4_t, poly8x16_t, poly8x16x2_t, poly8x16x3_t, poly8x16x4_t, poly16x4_t, poly16x8_t,
8030
                poly64x1_t, poly64x2_t, uint8x8_t, uint8x8x2_t, uint8x8x3_t, uint8x8x4_t, uint8x16_t,
8031
                uint8x16x2_t, uint8x16x3_t, uint8x16x4_t, uint16x4_t, uint16x8_t, uint32x2_t, uint32x4_t,
8032
                uint64x1_t, uint64x2_t
8033
            );
8034
            #[cfg(all(feature = "simd-nightly", target_arch = "arm"))]
8035
            #[rustfmt::skip]
8036
            test_simd_arch_mod!(arm, int8x4_t, uint8x4_t);
8037
        }
8038
    }
8039
}
8040
8041
#[cfg(kani)]
8042
mod proofs {
8043
    use super::*;
8044
8045
    impl kani::Arbitrary for DstLayout {
8046
        fn any() -> Self {
8047
            let align: NonZeroUsize = kani::any();
8048
            let size_info: SizeInfo = kani::any();
8049
8050
            kani::assume(align.is_power_of_two());
8051
            kani::assume(align < DstLayout::THEORETICAL_MAX_ALIGN);
8052
8053
            // For testing purposes, we most care about instantiations of
8054
            // `DstLayout` that can correspond to actual Rust types. We use
8055
            // `Layout` to verify that our `DstLayout` satisfies the validity
8056
            // conditions of Rust layouts.
8057
            kani::assume(
8058
                match size_info {
8059
                    SizeInfo::Sized { _size } => Layout::from_size_align(_size, align.get()),
8060
                    SizeInfo::SliceDst(TrailingSliceLayout { _offset, _elem_size }) => {
8061
                        // `SliceDst`` cannot encode an exact size, but we know
8062
                        // it is at least `_offset` bytes.
8063
                        Layout::from_size_align(_offset, align.get())
8064
                    }
8065
                }
8066
                .is_ok(),
8067
            );
8068
8069
            Self { align: align, size_info: size_info }
8070
        }
8071
    }
8072
8073
    impl kani::Arbitrary for SizeInfo {
8074
        fn any() -> Self {
8075
            let is_sized: bool = kani::any();
8076
8077
            match is_sized {
8078
                true => {
8079
                    let size: usize = kani::any();
8080
8081
                    kani::assume(size <= isize::MAX as _);
8082
8083
                    SizeInfo::Sized { _size: size }
8084
                }
8085
                false => SizeInfo::SliceDst(kani::any()),
8086
            }
8087
        }
8088
    }
8089
8090
    impl kani::Arbitrary for TrailingSliceLayout {
8091
        fn any() -> Self {
8092
            let elem_size: usize = kani::any();
8093
            let offset: usize = kani::any();
8094
8095
            kani::assume(elem_size < isize::MAX as _);
8096
            kani::assume(offset < isize::MAX as _);
8097
8098
            TrailingSliceLayout { _elem_size: elem_size, _offset: offset }
8099
        }
8100
    }
8101
8102
    #[kani::proof]
8103
    fn prove_dst_layout_extend() {
8104
        use crate::util::{core_layout::padding_needed_for, max, min};
8105
8106
        let base: DstLayout = kani::any();
8107
        let field: DstLayout = kani::any();
8108
        let packed: Option<NonZeroUsize> = kani::any();
8109
8110
        if let Some(max_align) = packed {
8111
            kani::assume(max_align.is_power_of_two());
8112
            kani::assume(base.align <= max_align);
8113
        }
8114
8115
        // The base can only be extended if it's sized.
8116
        kani::assume(matches!(base.size_info, SizeInfo::Sized { .. }));
8117
        let base_size = if let SizeInfo::Sized { _size: size } = base.size_info {
8118
            size
8119
        } else {
8120
            unreachable!();
8121
        };
8122
8123
        // Under the above conditions, `DstLayout::extend` will not panic.
8124
        let composite = base.extend(field, packed);
8125
8126
        // The field's alignment is clamped by `max_align` (i.e., the
8127
        // `packed` attribute, if any) [1].
8128
        //
8129
        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
8130
        //
8131
        //   The alignments of each field, for the purpose of positioning
8132
        //   fields, is the smaller of the specified alignment and the
8133
        //   alignment of the field's type.
8134
        let field_align = min(field.align, packed.unwrap_or(DstLayout::THEORETICAL_MAX_ALIGN));
8135
8136
        // The struct's alignment is the maximum of its previous alignment and
8137
        // `field_align`.
8138
        assert_eq!(composite.align, max(base.align, field_align));
8139
8140
        // Compute the minimum amount of inter-field padding needed to
8141
        // satisfy the field's alignment, and offset of the trailing field.
8142
        // [1]
8143
        //
8144
        // [1] Per https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers:
8145
        //
8146
        //   Inter-field padding is guaranteed to be the minimum required in
8147
        //   order to satisfy each field's (possibly altered) alignment.
8148
        let padding = padding_needed_for(base_size, field_align);
8149
        let offset = base_size + padding;
8150
8151
        // For testing purposes, we'll also construct `alloc::Layout`
8152
        // stand-ins for `DstLayout`, and show that `extend` behaves
8153
        // comparably on both types.
8154
        let base_analog = Layout::from_size_align(base_size, base.align.get()).unwrap();
8155
8156
        match field.size_info {
8157
            SizeInfo::Sized { _size: field_size } => {
8158
                if let SizeInfo::Sized { _size: composite_size } = composite.size_info {
8159
                    // If the trailing field is sized, the resulting layout
8160
                    // will be sized. Its size will be the sum of the
8161
                    // preceeding layout, the size of the new field, and the
8162
                    // size of inter-field padding between the two.
8163
                    assert_eq!(composite_size, offset + field_size);
8164
8165
                    let field_analog =
8166
                        Layout::from_size_align(field_size, field_align.get()).unwrap();
8167
8168
                    if let Ok((actual_composite, actual_offset)) = base_analog.extend(field_analog)
8169
                    {
8170
                        assert_eq!(actual_offset, offset);
8171
                        assert_eq!(actual_composite.size(), composite_size);
8172
                        assert_eq!(actual_composite.align(), composite.align.get());
8173
                    } else {
8174
                        // An error here reflects that composite of `base`
8175
                        // and `field` cannot correspond to a real Rust type
8176
                        // fragment, because such a fragment would violate
8177
                        // the basic invariants of a valid Rust layout. At
8178
                        // the time of writing, `DstLayout` is a little more
8179
                        // permissive than `Layout`, so we don't assert
8180
                        // anything in this branch (e.g., unreachability).
8181
                    }
8182
                } else {
8183
                    panic!("The composite of two sized layouts must be sized.")
8184
                }
8185
            }
8186
            SizeInfo::SliceDst(TrailingSliceLayout {
8187
                _offset: field_offset,
8188
                _elem_size: field_elem_size,
8189
            }) => {
8190
                if let SizeInfo::SliceDst(TrailingSliceLayout {
8191
                    _offset: composite_offset,
8192
                    _elem_size: composite_elem_size,
8193
                }) = composite.size_info
8194
                {
8195
                    // The offset of the trailing slice component is the sum
8196
                    // of the offset of the trailing field and the trailing
8197
                    // slice offset within that field.
8198
                    assert_eq!(composite_offset, offset + field_offset);
8199
                    // The elem size is unchanged.
8200
                    assert_eq!(composite_elem_size, field_elem_size);
8201
8202
                    let field_analog =
8203
                        Layout::from_size_align(field_offset, field_align.get()).unwrap();
8204
8205
                    if let Ok((actual_composite, actual_offset)) = base_analog.extend(field_analog)
8206
                    {
8207
                        assert_eq!(actual_offset, offset);
8208
                        assert_eq!(actual_composite.size(), composite_offset);
8209
                        assert_eq!(actual_composite.align(), composite.align.get());
8210
                    } else {
8211
                        // An error here reflects that composite of `base`
8212
                        // and `field` cannot correspond to a real Rust type
8213
                        // fragment, because such a fragment would violate
8214
                        // the basic invariants of a valid Rust layout. At
8215
                        // the time of writing, `DstLayout` is a little more
8216
                        // permissive than `Layout`, so we don't assert
8217
                        // anything in this branch (e.g., unreachability).
8218
                    }
8219
                } else {
8220
                    panic!("The extension of a layout with a DST must result in a DST.")
8221
                }
8222
            }
8223
        }
8224
    }
8225
8226
    #[kani::proof]
8227
    #[kani::should_panic]
8228
    fn prove_dst_layout_extend_dst_panics() {
8229
        let base: DstLayout = kani::any();
8230
        let field: DstLayout = kani::any();
8231
        let packed: Option<NonZeroUsize> = kani::any();
8232
8233
        if let Some(max_align) = packed {
8234
            kani::assume(max_align.is_power_of_two());
8235
            kani::assume(base.align <= max_align);
8236
        }
8237
8238
        kani::assume(matches!(base.size_info, SizeInfo::SliceDst(..)));
8239
8240
        let _ = base.extend(field, packed);
8241
    }
8242
8243
    #[kani::proof]
8244
    fn prove_dst_layout_pad_to_align() {
8245
        use crate::util::core_layout::padding_needed_for;
8246
8247
        let layout: DstLayout = kani::any();
8248
8249
        let padded: DstLayout = layout.pad_to_align();
8250
8251
        // Calling `pad_to_align` does not alter the `DstLayout`'s alignment.
8252
        assert_eq!(padded.align, layout.align);
8253
8254
        if let SizeInfo::Sized { _size: unpadded_size } = layout.size_info {
8255
            if let SizeInfo::Sized { _size: padded_size } = padded.size_info {
8256
                // If the layout is sized, it will remain sized after padding is
8257
                // added. Its sum will be its unpadded size and the size of the
8258
                // trailing padding needed to satisfy its alignment
8259
                // requirements.
8260
                let padding = padding_needed_for(unpadded_size, layout.align);
8261
                assert_eq!(padded_size, unpadded_size + padding);
8262
8263
                // Prove that calling `DstLayout::pad_to_align` behaves
8264
                // identically to `Layout::pad_to_align`.
8265
                let layout_analog =
8266
                    Layout::from_size_align(unpadded_size, layout.align.get()).unwrap();
8267
                let padded_analog = layout_analog.pad_to_align();
8268
                assert_eq!(padded_analog.align(), layout.align.get());
8269
                assert_eq!(padded_analog.size(), padded_size);
8270
            } else {
8271
                panic!("The padding of a sized layout must result in a sized layout.")
8272
            }
8273
        } else {
8274
            // If the layout is a DST, padding cannot be statically added.
8275
            assert_eq!(padded.size_info, layout.size_info);
8276
        }
8277
    }
8278
}