// 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:////// ```textLines 1–500 of 7614. Load more
// 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