//! Many functions in this module take raw pointers as arguments and read from or write to them. For
//! this to be safe, these pointers must be *valid* for the given access. Whether a pointer is valid
//! accessed (i.e., how many bytes are read/written) -- it makes no sense to ask "is this pointer
//! valid"; one has to ask "is this pointer valid for a given access". Most functions use `*mut T`
//! and `*const T` to access only a single value, in which case the documentation omits the size and
//! means out-of-bounds pointers, pointers to freed memory, null pointers, and pointers created with
//! * You must enforce Rust's aliasing rules. The exact aliasing rules are not decided yet, so we
//! * When creating a mutable reference, then while this reference exists, the memory it points to
//! * When creating a shared reference, then while this reference exists, the memory it points to
//! side-effects, and writes must become visible to other threads using the usual synchronization
//! To rationalize claims like this, pointers need to somehow be *more* than just their addresses:
//! * The **provenance** it has, defining the memory it has permission to access. Provenance can be
//! * Temporal: The timespan during which the pointer is allowed to access those memory addresses.
//! * Mutability: Whether the pointer may only access the memory for reads, or also access it for
//! provenance, limiting how much memory it can access or how long it's valid for (i.e. borrowing a
//! subfield and subslicing can shrink the spatial component of provenance, and all borrowing can
//! * It is undefined behavior to access memory through a pointer that does not have provenance over
//! * It is undefined behavior to [`offset`] a pointer across a memory range that is not contained
//! means: the lineage of a pointer is traced back to the Original Pointer it descends from, and
//! * Create a pointer without provenance from just an address (see [`without_provenance`]). Such a
//! pointer cannot be used for memory accesses (except for zero-sized accesses). This can still be
//! useful for sentinel values like `null` *or* to represent a tagged pointer that will never be
//! dereferenceable. In general, it is always sound for an integer to pretend to be a pointer "for
//! which have "no" provenance. In particular, this makes it sound to do pointer tagging tricks.
//! * Compare arbitrary pointers by address. Pointer comparison ignores provenance and addresses
//! *are* just integers, so there is always a coherent answer, even if the pointers are dangling
//! or from different provenances. Note that if you get "lucky" and notice that a pointer at the
//! From this discussion, it becomes very clear that a `usize` *cannot* accurately represent a pointer,
//! and converting from a pointer to a `usize` is generally an operation which *only* extracts the
//! Rust provides two ways of dealing with this situation: *Strict Provenance* and *Exposed Provenance*.
//! Note that a pointer *can* represent a `usize` (via [`without_provenance`]), so the right type to
//! Entirely avoiding integer-to-pointer casts successfully side-steps the inherent ambiguity of
//! that operation. This benefits compiler optimizations, and it is pretty much a requirement for
//! using tools like [Miri] and architectures like [CHERI] that aim to detect and diagnose pointer
//! The key insight to making programming without integer-to-pointer casts *at all* viable is the
//! To help make it clear that code is "following" Strict Provenance semantics, we also provide an
//! pointer-integer-pointer roundtrip. In the future we may provide a lint for pointer<->integer
//! operation is casts from `usize` to a pointer. For code which *does* cast a `usize` to a pointer,
//! (Yes, if you've been using [`AtomicUsize`] for pointers in concurrent datastructures, you should
//! be using [`AtomicPtr`] instead. If that messes up the way you atomically manipulate pointers,
//! Situations where a valid pointer *must* be created from just an address, such as baremetal code
//! accessing a memory-mapped interface at a fixed address, cannot currently be handled with strict
//! This is by design: the goal of Strict Provenance is to provide a clear specification that we are
//! where avoiding them would require major refactoring. Legacy platform APIs also regularly assume
//! Rust's model for dealing with integer-to-pointer casts is called *Exposed Provenance*. However,
//! the semantics of Exposed Provenance are on much less solid footing than Strict Provenance, and
//! at this point it is not yet clear whether a satisfying unambiguous semantics can be defined for
//! Exposed Provenance. (If that sounds bad, be reassured that other popular languages that provide
//! integer-to-pointer casts are not faring any better.) Furthermore, Exposed Provenance will not
//! Exposed Provenance is provided by the [`expose_provenance`] and [`with_exposed_provenance`] methods,
//! pointer to a global list of 'exposed' provenances. (This list is purely conceptual, it exists
//! Memory which is outside the control of the Rust abstract machine (MMIO registers, for example)
//! is always considered to be exposed, so long as this memory is disjoint from memory that will
//! - [`with_exposed_provenance`] can be used to construct a pointer with one of these previously
//! 'exposed' provenances. [`with_exposed_provenance`] takes only `addr: usize` as arguments, so
//! unlike in [`with_addr`] there is no indication of what the correct provenance for the returned
//! pointer is -- and that is exactly what makes integer-to-pointer casts so tricky to rigorously
//! specify! The compiler will do its best to pick the right provenance for you, but currently we
//! cannot provide any guarantees about which provenance the resulting pointer will have. Only one
//! If at all possible, we encourage code to be ported to [Strict Provenance] APIs, thus avoiding
//! the need for Exposed Provenance. Maximizing the amount of such code is a major win for avoiding
//! specification complexity and to facilitate adoption of tools like [CHERI] and [Miri] that can be
//! a big help in increasing the confidence in (unsafe) Rust code. However, we acknowledge that this
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes, and must remain valid even
/// Additionally, note that changing `*dst` in this way can easily lead to undefined behavior (UB)
// `bool` it must be 0 or 1, if it is a reference then it must be dereferenceable. `drop_in_place`
// only requires that `*to_drop` be "valid for dropping" and we have not defined what that means. In
/// non-zero-sized memory accesses with a no-provenance pointer are UB. No-provenance pointers are
/// This is different from `addr as *const T`, which creates a pointer that picks up a previously
/// non-zero-sized memory accesses with a no-provenance pointer are UB. No-provenance pointers are
/// This is fully equivalent to `addr as *const T`. The provenance of the returned pointer is that
/// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory
/// always considered to be accessible with an exposed provenance, so long as this memory is disjoint
/// The exact provenance that gets picked is not specified. The compiler will do its best to pick
/// If there is *no* previously 'exposed' provenance that justifies the way the returned pointer
/// will be used, the program has undefined behavior. In particular, the aliasing rules still apply:
/// Due to its inherent ambiguity, this operation may not be supported by tools that help you to
#[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
/// This is fully equivalent to `addr as *mut T`. The provenance of the returned pointer is that
/// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory
/// always considered to be accessible with an exposed provenance, so long as this memory is disjoint
/// from memory that will be used by the abstract machine such as the stack, heap, and statics.
/// The exact provenance that gets picked is not specified. The compiler will do its best to pick
/// If there is *no* previously 'exposed' provenance that justifies the way the returned pointer
/// will be used, the program has undefined behavior. In particular, the aliasing rules still apply:
/// Due to its inherent ambiguity, this operation may not be supported by tools that help you to
/// Provenance][self#strict-provenance] APIs such as [`with_addr`][pointer::with_addr] wherever
#[allow(fuzzy_provenance_casts)] // this *is* the explicit provenance API one should use instead
/// For `r: &T`, `from_ref(r)` is equivalent to `r as *const T` (except for the caveat noted below),
/// but is a bit safer since it will never silently change type or mutability, in particular if the
/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
/// The caller must also ensure that the memory the pointer (non-transitively) points to is never
/// written to (except inside an `UnsafeCell`) using this pointer or any pointer derived from it. If
/// you need to mutate the pointee, use [`from_mut`]. Specifically, to turn a mutable reference `m:
/// &mut T` into `*const T`, prefer `from_mut(m).cast_const()` to obtain a pointer that can later be
/// Note that this has subtle interactions with the rules for lifetime extension of temporaries in
/// below), but is a bit safer since it will never silently change type or mutability, in particular
/// The caller must ensure that the pointee outlives the pointer this function returns, or else it
/// Note that this has subtle interactions with the rules for lifetime extension of temporaries in
/// * The operation is "untyped" in the sense that data may be uninitialized or otherwise violate
/// * Both `x` and `y` must be [valid] for both reads and writes. They must remain valid even when the
/// other pointer is written. (This means if the memory ranges overlap, the two pointers must not
/// The operation is "untyped" in the sense that data may be uninitialized or otherwise violate the
/// assert_eq!({packed.unaligned}, 42); // `{...}` forces copying the field instead of creating a reference.
/// Volatile operations are intended to act on I/O memory. As such, they are considered externally
/// observable events (just like syscalls, but less opaque), and are guaranteed to not be elided or
/// reordered by the compiler across other externally observable events. With this in mind, there
/// - When a volatile operation is used for memory inside an [allocation], it behaves exactly like
/// above). This implies that the operation will actually access memory and not e.g. be lowered to
/// reusing data from a previous read. Other than that, all the usual rules for memory accesses
/// apply (including provenance). In particular, just like in C, whether an operation is volatile
/// has no bearing whatsoever on questions involving concurrent accesses from multiple threads.
/// - Volatile operations, however, may also be used to access memory that is _outside_ of any Rust
/// mapping, most commonly at fixed addresses reserved by the hardware. These often have special
/// Here, any address value is possible, including 0 and [`usize::MAX`], so long as the semantics
/// irrelevant, and it can be created with [`without_provenance`]. The access must not trap. It
/// Note that volatile memory operations where T is a zero-sized type are noops and may be ignored.
/// [`Copy`]. If `T` is not [`Copy`], using both the returned value and the value at `*src` can
/// [violate memory safety][read-ownership]. However, storing non-[`Copy`] types in volatile memory
/// Performs a volatile write of a memory location with the given value without reading or dropping
/// Volatile operations are intended to act on I/O memory. As such, they are considered externally
/// observable events (just like syscalls), and are guaranteed to not be elided or reordered by the
/// compiler across other externally observable events. With this in mind, there are two cases of
/// - When a volatile operation is used for memory inside an [allocation], it behaves exactly like
/// [`write`][write()], except for the additional guarantee that it won't be elided or reordered
/// lowered to a register access. Other than that, all the usual rules for memory accesses apply
/// (including provenance). In particular, just like in C, whether an operation is volatile has no
/// bearing whatsoever on questions involving concurrent access from multiple threads. Volatile
/// - Volatile operations, however, may also be used to access memory that is _outside_ of any Rust
/// allocation. In this use-case, the pointer does *not* have to be [valid] for writes. This is
/// mapping, most commonly at fixed addresses reserved by the hardware. These often have special
/// Here, any address value is possible, including 0 and [`usize::MAX`], so long as the semantics
/// irrelevant, and it can be created with [`without_provenance`]. The access must not trap. It
/// Note that volatile memory operations on zero-sized types (e.g., if a zero-sized type is passed
/// allocations or resources, so care should be taken not to overwrite an object that should be
/// dropped when operating on Rust memory. Additionally, it does not drop `src`. Semantically, `src`
/// Calculate an element-offset (not byte-offset) that when added to a given pointer `p`, increases `p`'s alignment to at least the given alignment `a`.
/// power-of-two, it will probably be more prudent to just change to a naive implementation rather
// FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <=
// misaligned, there isn’t an obvious relationship between `stride` and `a` that we can take an
/// However, note that comparing trait object pointers (`*const dyn Trait`) is unreliable: pointers
/// to values of the same underlying type can compare inequal (because vtables are duplicated in
/// multiple codegen units), and pointers to values of *different* underlying type can compare equal
/// There are **very few guarantees** about how functions are compiled and they have no intrinsic
/// dbg!(std::ptr::fn_addr_eq(f, g), std::ptr::fn_addr_eq(f, h)); // not guaranteed to be equal
/// * `T` is the same type as `U`, `T` is a [subtype] of `U`, or `U` is a [subtype] of `T`, and
/// result of `addr_of!` inherits all permissions from that raw pointer. However, if the place is
/// based on a reference, local variable, or `static`, then until all details are decided, the same
/// rules as for shared references apply: it is UB to write through a pointer created with this
/// operation, except for bytes located inside an `UnsafeCell`. Use `&raw mut` (or [`addr_of_mut`])
/// The `expr` in `addr_of!(expr)` is evaluated as a place expression, but never loads from the
/// place or requires the place to be dereferenceable. This means that `addr_of!((*ptr).field)`
/// still requires the projection to `field` to be in-bounds, using the same rules as [`offset`].
/// However, `addr_of!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
/// `addr_of!` like everywhere else, in which case a reference is created to call `Deref::deref` or
/// See the [`offset`] docs for a full list of requirements for inbounds pointer arithmetic; the
/// same requirements apply to field projections, even inside `addr_of!`. (In particular, it makes
/// The `expr` in `addr_of_mut!(expr)` is evaluated as a place expression, but never loads from the
/// place or requires the place to be dereferenceable. This means that `addr_of_mut!((*ptr).field)`
/// still requires the projection to `field` to be in-bounds, using the same rules as [`offset`].
/// However, `addr_of_mut!(*ptr)` is defined behavior even if `ptr` is null, dangling, or misaligned.
/// `addr_of_mut!` like everywhere else, in which case a reference is created to call `Deref::deref`
/// or `Index::index`, respectively. The statements above only apply when no such coercions are
/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
/// See the [`offset`] docs for a full list of requirements for inbounds pointer arithmetic; the
/// same requirements apply to field projections, even inside `addr_of_mut!`. (In particular, it