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