7614 lines · 270.4 KB · Rust
RawDownload
// SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT//// Copyright 2018 The Fuchsia Authors//// Licensed under the 2-Clause BSD License <LICENSE-BSD or// https://opensource.org/license/bsd-2-clause>, Apache License, Version 2.0// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.// This file may not be copied, modified, or distributed except according to// those terms. // After updating the following doc comment, make sure to run the following// command to update `README.md` based on its contents:////   (cd .. && cargo -q run --manifest-path tools/Cargo.toml -p generate-readme) > README.md //! ***<span style="font-size: 140%">Fast, safe, <span//! style="color:red;">compile error</span>. Pick two.</span>***//!//! Zerocopy makes zero-cost memory manipulation effortless. We write `unsafe`//! so you don't have to.//!//! *For an overview of what's changed from zerocopy 0.7, check out our [release//! notes][release-notes], which include a step-by-step upgrading guide.*//!//! *Have questions? Need more out of zerocopy? Submit a [customer request//! issue][customer-request-issue] or ask the maintainers on//! [GitHub][github-q-a] or [Discord][discord]!*//!//! [customer-request-issue]: https://github.com/google/zerocopy/issues/new/choose//! [release-notes]: https://github.com/google/zerocopy/discussions/1680//! [github-q-a]: https://github.com/google/zerocopy/discussions/categories/q-a//! [discord]: https://discord.gg/MAvWH2R6zk//!//! # Overview//!//! ##### Conversion Traits//!//! Zerocopy provides four derivable traits for zero-cost conversions://! - [`TryFromBytes`] indicates that a type may safely be converted from//!   certain byte sequences (conditional on runtime checks)//! - [`FromZeros`] indicates that a sequence of zero bytes represents a valid//!   instance of a type//! - [`FromBytes`] indicates that a type may safely be converted from an//!   arbitrary byte sequence//! - [`IntoBytes`] indicates that a type may safely be converted *to* a byte//!   sequence//!//! These traits support sized types, slices, and [slice DSTs][slice-dsts].//!//! [slice-dsts]: KnownLayout#dynamically-sized-types//!//! ##### Marker Traits//!//! Zerocopy provides three derivable marker traits that do not provide any//! functionality themselves, but are required to call certain methods provided//! by the conversion traits://! - [`KnownLayout`] indicates that zerocopy can reason about certain layout//!   qualities of a type//! - [`Immutable`] indicates that a type is free from interior mutability,//!   except by ownership or an exclusive (`&mut`) borrow//! - [`Unaligned`] indicates that a type's alignment requirement is 1//!//! You should generally derive these marker traits whenever possible.//!//! ##### Conversion Macros//!//! Zerocopy provides six macros for safe casting between types://!//! - ([`try_`][try_transmute])[`transmute`] (conditionally) converts a value of//!   one type to a value of another type of the same size//! - ([`try_`][try_transmute_mut])[`transmute_mut`] (conditionally) converts a//!   mutable reference of one type to a mutable reference of another type of//!   the same size//! - ([`try_`][try_transmute_ref])[`transmute_ref`] (conditionally) converts a//!   mutable or immutable reference of one type to an immutable reference of//!   another type of the same size//!//! These macros perform *compile-time* size and alignment checks, meaning that//! unconditional casts have zero cost at runtime. Conditional casts do not need//! to validate size or alignment runtime, but do need to validate contents.//!//! These macros cannot be used in generic contexts. For generic conversions,//! use the methods defined by the [conversion traits](#conversion-traits).//!//! ##### Byteorder-Aware Numerics//!//! Zerocopy provides byte-order aware integer types that support these//! conversions; see the [`byteorder`] module. These types are especially useful//! for network parsing.//!//! # Cargo Features//!//! - **`alloc`**//!   By default, `zerocopy` is `no_std`. When the `alloc` feature is enabled,//!   the `alloc` crate is added as a dependency, and some allocation-related//!   functionality is added.//!//! - **`std`**//!   By default, `zerocopy` is `no_std`. When the `std` feature is enabled, the//!   `std` crate is added as a dependency (ie, `no_std` is disabled), and//!   support for some `std` types is added. `std` implies `alloc`.//!//! - **`derive`**//!   Provides derives for the core marker traits via the `zerocopy-derive`//!   crate. These derives are re-exported from `zerocopy`, so it is not//!   necessary to depend on `zerocopy-derive` directly.//!//!   However, you may experience better compile times if you instead directly//!   depend on both `zerocopy` and `zerocopy-derive` in your `Cargo.toml`,//!   since doing so will allow Rust to compile these crates in parallel. To do//!   so, do *not* enable the `derive` feature, and list both dependencies in//!   your `Cargo.toml` with the same leading non-zero version number; e.g://!//!   ```toml//!   [dependencies]//!   zerocopy = "0.X"//!   zerocopy-derive = "0.X"//!   ```//!//!   To avoid the risk of [duplicate import errors][duplicate-import-errors] if//!   one of your dependencies enables zerocopy's `derive` feature, import//!   derives as `use zerocopy_derive::*` rather than by name (e.g., `use//!   zerocopy_derive::FromBytes`).//!//! - **`simd`**//!   When the `simd` feature is enabled, `FromZeros`, `FromBytes`, and//!   `IntoBytes` impls are emitted for all stable SIMD types which exist on the//!   target platform. Note that the layout of SIMD types is not yet stabilized,//!   so these impls may be removed in the future if layout changes make them//!   invalid. For more information, see the Unsafe Code Guidelines Reference//!   page on the [layout of packed SIMD vectors][simd-layout].//!//! - **`simd-nightly`**//!   Enables the `simd` feature and adds support for SIMD types which are only//!   available on nightly. Since these types are unstable, support for any type//!   may be removed at any point in the future.//!//! - **`float-nightly`**//!   Adds support for the unstable `f16` and `f128` types. These types are//!   not yet fully implemented and may not be supported on all platforms.//!//! [duplicate-import-errors]: https://github.com/google/zerocopy/issues/1587//! [simd-layout]: https://rust-lang.github.io/unsafe-code-guidelines/layout/packed-simd-vectors.html//!//! # Build Tuning//!//! ## `--cfg zerocopy_inline_always`//!//! Upgrades `#[inline]` to `#[inline(always)]` on many of zerocopy's public//! functions and methods. This provides a narrowly-scoped alternative that//! *may* improve the optimization of hot paths using zerocopy without the broad//! compile-time penalties of configuring `codegen-units=1`.//!//! # Security Ethos//!//! Zerocopy is expressly designed for use in security-critical contexts. We//! strive to ensure that that zerocopy code is sound under Rust's current//! memory model, and *any future memory model*. We ensure this by://! - **...not 'guessing' about Rust's semantics.**//!   We annotate `unsafe` code with a precise rationale for its soundness that//!   cites a relevant section of Rust's official documentation. When Rust's//!   documented semantics are unclear, we work with the Rust Operational//!   Semantics Team to clarify Rust's documentation.//! - **...rigorously testing our implementation.**//!   We run tests using [Miri], ensuring that zerocopy is sound across a wide//!   array of supported target platforms of varying endianness and pointer//!   width, and across both current and experimental memory models of Rust.//! - **...formally proving the correctness of our implementation.**//!   We apply formal verification tools like [Kani][kani] to prove zerocopy's//!   correctness.//!//! For more information, see our full [soundness policy].//!//! [Miri]: https://github.com/rust-lang/miri//! [Kani]: https://github.com/model-checking/kani//! [soundness policy]: https://github.com/google/zerocopy/blob/main/zerocopy/POLICIES.md#soundness//!//! # Relationship to Project Safe Transmute//!//! [Project Safe Transmute] is an official initiative of the Rust Project to//! develop language-level support for safer transmutation. The Project consults//! with crates like zerocopy to identify aspects of safer transmutation that//! would benefit from compiler support, and has developed an [experimental,//! compiler-supported analysis][mcp-transmutability] which determines whether,//! for a given type, any value of that type may be soundly transmuted into//! another type. Once this functionality is sufficiently mature, zerocopy//! intends to replace its internal transmutability analysis (implemented by our//! custom derives) with the compiler-supported one. This change will likely be//! an implementation detail that is invisible to zerocopy's users.//!//! Project Safe Transmute will not replace the need for most of zerocopy's//! higher-level abstractions. The experimental compiler analysis is a tool for//! checking the soundness of `unsafe` code, not a tool to avoid writing//! `unsafe` code altogether. For the foreseeable future, crates like zerocopy//! will still be required in order to provide higher-level abstractions on top//! of the building block provided by Project Safe Transmute.//!//! [Project Safe Transmute]: https://rust-lang.github.io/rfcs/2835-project-safe-transmute.html//! [mcp-transmutability]: https://github.com/rust-lang/compiler-team/issues/411//!//! # MSRV//!//! See our [MSRV policy].//!//! [MSRV policy]: https://github.com/google/zerocopy/blob/main/zerocopy/POLICIES.md#msrv//!//! # Changelog//!//! Zerocopy uses [GitHub Releases].//!//! [GitHub Releases]: https://github.com/google/zerocopy/releases//!//! # Thanks//!//! Zerocopy is maintained by engineers at Google with help from [many wonderful//! contributors][contributors]. Thank you to everyone who has lent a hand in//! making Rust a little more secure!//!//! [contributors]: https://github.com/google/zerocopy/graphs/contributors // Sometimes we want to use lints which were added after our MSRV.// `unknown_lints` is `warn` by default and we deny warnings in CI, so without// this attribute, any unknown lint would cause a CI failure when testing with// our MSRV.#![allow(unknown_lints, non_local_definitions, unreachable_patterns)]#![deny(renamed_and_removed_lints)]#![deny(    anonymous_parameters,    deprecated_in_future,    late_bound_lifetime_arguments,    missing_copy_implementations,    missing_debug_implementations,    missing_docs,    path_statements,    patterns_in_fns_without_body,    rust_2018_idioms,    trivial_numeric_casts,    unreachable_pub,    unsafe_op_in_unsafe_fn,    unused_extern_crates,    // We intentionally choose not to deny `unused_qualifications`. When items    // are added to the prelude (e.g., `core::mem::size_of`), this has the    // consequence of making some uses trigger this lint on the latest toolchain    // (e.g., `mem::size_of`), but fixing it (e.g. by replacing with `size_of`)    // does not work on older toolchains.    //    // We tested a more complicated fix in #1413, but ultimately decided that,    // since this lint is just a minor style lint, the complexity isn't worth it    // - it's fine to occasionally have unused qualifications slip through,    // especially since these do not affect our user-facing API in any way.    variant_size_differences)]#![cfg_attr(    __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS,    deny(fuzzy_provenance_casts, lossy_provenance_casts))]#![deny(    clippy::all,    clippy::alloc_instead_of_core,    clippy::arithmetic_side_effects,    clippy::as_underscore,    clippy::assertions_on_result_states,    clippy::as_conversions,    clippy::correctness,    clippy::dbg_macro,    clippy::decimal_literal_representation,    clippy::double_must_use,    clippy::get_unwrap,    clippy::indexing_slicing,    clippy::missing_inline_in_public_items,    clippy::missing_safety_doc,    clippy::multiple_unsafe_ops_per_block,    clippy::must_use_candidate,    clippy::must_use_unit,    clippy::obfuscated_if_else,    clippy::perf,    clippy::print_stdout,    clippy::return_self_not_must_use,    clippy::std_instead_of_core,    clippy::style,    clippy::suspicious,    clippy::todo,    clippy::undocumented_unsafe_blocks,    clippy::unimplemented,    clippy::unnested_or_patterns,    clippy::unwrap_used,    clippy::use_debug)]// `clippy::incompatible_msrv` (implied by `clippy::suspicious`): This sometimes// has false positives, and we test on our MSRV in CI, so it doesn't help us// anyway.#![allow(clippy::needless_lifetimes, clippy::type_complexity, clippy::incompatible_msrv)]#![deny(    rustdoc::bare_urls,    rustdoc::broken_intra_doc_links,    rustdoc::invalid_codeblock_attributes,    rustdoc::invalid_html_tags,    rustdoc::invalid_rust_codeblocks,    rustdoc::missing_crate_level_docs,    rustdoc::private_intra_doc_links)]// In test code, it makes sense to weight more heavily towards concise, readable// code over correct or debuggable code.#![cfg_attr(any(test, kani), allow(    // In tests, you get line numbers and have access to source code, so panic    // messages are less important. You also often unwrap a lot, which would    // make expect'ing instead very verbose.    clippy::unwrap_used,    // In tests, there's no harm to "panic risks" - the worst that can happen is    // that your test will fail, and you'll fix it. By contrast, panic risks in    // production code introduce the possibly of code panicking unexpectedly "in    // the field".    clippy::arithmetic_side_effects,    clippy::indexing_slicing,))]#![cfg_attr(not(any(test, kani, feature = "std")), no_std)]#![cfg_attr(    all(feature = "simd-nightly", target_arch = "arm"),    feature(stdarch_arm_neon_intrinsics))]#![cfg_attr(    all(feature = "simd-nightly", any(target_arch = "powerpc", target_arch = "powerpc64")),    feature(stdarch_powerpc))]#![cfg_attr(feature = "float-nightly", feature(f16, f128))]#![cfg_attr(doc_cfg, feature(doc_cfg))]#![cfg_attr(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, feature(coverage_attribute))]#![cfg_attr(    any(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, miri),    feature(layout_for_ptr))]#![cfg_attr(all(test, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS), feature(test))] // This is a hack to allow zerocopy-derive derives to work in this crate. They// assume that zerocopy is linked as an extern crate, so they access items from// it as `zerocopy::Xxx`. This makes that still work.#[cfg(any(feature = "derive", test))]extern crate self as zerocopy; #[cfg(all(test, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS))]extern crate test; #[doc(hidden)]#[macro_use]pub mod util; pub mod byte_slice;pub mod byteorder;mod deprecated; #[cfg(__ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE)]pub mod doctests; // This module is `pub` so that zerocopy's error types and error handling// documentation is grouped together in a cohesive module. In practice, we// expect most users to use the re-export of `error`'s items to avoid identifier// stuttering.pub mod error;mod impls;#[doc(hidden)]pub mod layout;mod macros;#[cfg_attr(not(zerocopy_unstable_ptr), doc(hidden))]#[cfg_attr(doc_cfg, doc(cfg(zerocopy_unstable_ptr)))]pub mod pointer;mod r#ref;mod split_at;// FIXME(#252): If we make this pub, come up with a better name.mod wrappers; use core::{    cell::{Cell, UnsafeCell},    cmp::Ordering,    fmt::{self, Debug, Display, Formatter},    hash::Hasher,    marker::PhantomData,    mem::{self, ManuallyDrop, MaybeUninit as CoreMaybeUninit},    num::{        NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,        NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,    },    ops::{Deref, DerefMut},    ptr::{self, NonNull},    slice,};#[cfg(feature = "std")]use std::io; #[doc(hidden)]pub use crate::pointer::{    invariant::{self, BecauseExclusive},    PtrInner,};pub use crate::{    byte_slice::*,    byteorder::*,    error::*,    r#ref::*,    split_at::{Split, SplitAt},    wrappers::*,}; #[cfg(any(feature = "alloc", test, kani))]extern crate alloc;#[cfg(any(feature = "alloc", test))]use alloc::{boxed::Box, vec::Vec};#[cfg(any(feature = "alloc", test))]use core::alloc::Layout; // Used by `KnownLayout`.#[doc(hidden)]pub use crate::layout::*;// Used by `TryFromBytes::is_bit_valid`.#[doc(hidden)]pub use crate::pointer::{invariant::BecauseImmutable, Maybe, Ptr};// For each trait polyfill, as soon as the corresponding feature is stable, the// polyfill import will be unused because method/function resolution will prefer// the inherent method/function over a trait method/function. Thus, we suppress// the `unused_imports` warning.//// See the documentation on `util::polyfills` for more information.#[allow(unused_imports)]use crate::util::polyfills::{self, NonNullExt as _, NumExt as _};#[cfg_attr(not(zerocopy_unstable_ptr), doc(hidden))]#[cfg_attr(doc_cfg, doc(cfg(zerocopy_unstable_ptr)))]pub use crate::util::MetadataOf; #[cfg(all(test, not(__ZEROCOPY_INTERNAL_USE_ONLY_DEV_MODE)))]const _: () = {    #[deprecated = "Development of zerocopy using cargo is not supported. Please use `cargo.sh` or `win-cargo.bat` instead."]    #[allow(unused)]    const WARNING: () = ();    #[warn(deprecated)]    WARNING}; #[cfg(all(any(feature = "derive", test), zerocopy_unstable_linux))]pub use zerocopy_derive::most_traits;/// Implements [`KnownLayout`].////// This derive analyzes various aspects of a type's layout that are needed for/// some of zerocopy's APIs. It can be applied to structs, enums, and unions;/// e.g.:////// ```/// # use zerocopy_derive::KnownLayout;/// #[derive(KnownLayout)]/// struct MyStruct {/// # /*///     .../// # *//// }////// #[derive(KnownLayout)]/// enum MyEnum {/// #   V00,/// # /*///     .../// # *//// }////// #[derive(KnownLayout)]/// union MyUnion {/// #   variant: u8,/// # /*///     .../// # *//// }/// ```////// # Limitations////// This derive cannot currently be applied to unsized structs without an/// explicit `repr` attribute.////// Some invocations of this derive run afoul of a [known bug] in Rust's type/// privacy checker. For example, this code:////// ```compile_fail,E0446/// use zerocopy::*;/// # use zerocopy_derive::*;////// #[derive(KnownLayout)]/// #[repr(C)]/// pub struct PublicType {///     leading: Foo,///     trailing: Bar,/// }////// #[derive(KnownLayout)]/// struct Foo;////// #[derive(KnownLayout)]/// struct Bar;/// ```////// ...results in a compilation error:////// ```text

Lines 1–500 of 7614.