Expand description
In the Rust standard library, *const T and *mut T are wholly discrete and
unrelated types, except that *mut T coerces into *const T via a compiler
builtin. *mut T is notionally a subtype of *const T, but this relation is
not expressed in the type system available to Rust user code.
This crate produces a unifying wrapper type over both pointers, called
Pointer. It, like the raw pointer primitives in the standard library, is
generic over the pointee T. Unlike the raw pointer primitives, it is also
generic over a P: Permission token.
§The Permission System
The Permission trait and its implementors, Shared and Unique, provide
a library-level reification of the Stacked Borrows model being built inside
the Rust compiler’s provenance system. You can see in the Stacked Borrows
documentation that it has a similar permission system that describes Unique and
two different kinds of Shared. Pointdexter views the SharedReadWrite and
SharedReadOnly values not as discrete states, but as stateful lenses over an
original provenance.
In particular, any Unique permission in Pointdexter can be degraded to an
equivalent of the Stacked-Borrows SharedReadWrite by pushing it into a type
stack, (Shared, Unique). Pointdexter implements the Permission trait on all
(Shared, impl Permission) tuples, which allows client code to always be able
to push and unwind sharing information and change the type of a Pointer,
rather than add runtime state that causes ABI changes.
§Usage
This crate is primarily useful for other library or intermediate code that needs to generalize over write permissions. Applications tend to not need to be general in the same way and may benefit less from it.
All pointers and references can be converted into their corresponding Pointer,
Reference, or NonNullPointer using .into(), .try_into(), or ::new().
Once converted, all stable standard-library APIs continue to exist.
This library was extracted from bitvec, where it was first built to support
the custom pointer type that powers it. That crate’s source code is likely the
best (and also likely only) example of how Pointdexter is meant to be used as an
implementation detail of other libraries.
Pointdexter is a long name, so the package is called ptxr. If you feel very
confident, you can alias it to ptr and completely shadow the core module.
use ptxr::*;
let mut data = 5i32;
let cptr: ptxr::Pointer<i32, Shared> = (&data).into();
let mptr: ptxr::Pointer<i32, Unique> = (&mut data).into();
unsafe { mptr.write(10); }
let sptr: ptxr::Pointer<i32, (Shared, Unique)> = mptr.cast_shared();
// unsafe { sptr.write(15); }
// contaminated pointers can't write anymore!
assert!(cptr.try_cast_unique().is_err());
let mptr = sptr.try_cast_unique()
.expect("this pointer was mutable once, and can be again");
unsafe { mptr.write(20); }
assert_eq!(unsafe { cptr.read() }, 20);§Rust Version Compatibility
This crate begins its Rust support at 1.85, and uses feature gates to add APIs for successive releases.
If you want to use this crate on earlier Rust versions, please file an issue and I will lower the floor accordingly.
Enable the feature rust_1xy, where xy is the minor version of Rust you use,
to enable the pointer APIs that are stable in your compiler. Use rust_now if
you track the stable release train. Features begin at rust_186, as Rust 1.85
is the baseline and is always available.
Note that rust_now is a default feature! If you are pinning a Rust rather
than floating on the stable series, you must set
[dependencies.ptxr]
default-features = false
features = ["rust_1xy"]Macros§
- pointer_
dispatch - Helper to route wrapper functions to their underlying impl.
Structs§
- NonNull
Pointer - Like
Pointer, but guaranteed to be non-zero. - NonUnique
Error - Emitted when a
Sharedprovenance tries to upgrade toUniquewithout a pedigree. - Null
Pointer Error - Emitted when a null-pointer is provided to an API that requires non-null pointers.
- Pointer
- Unifying bridge over
*const Tand*mut T. - Shared
- Shared Provenance
- Unique
- Unique Provenance
Traits§
- Permission
- Trait-level pointer access permissions.
Functions§
- addr_eq
- Compares the addresses of two pointers for equality, ignoring any metadata in fat pointers.
- copy⚠
- Copies
count * size_of::<T>()bytes from the source to the destination. The two regions may overlap. - copy_
nonoverlapping ⚠ - Copies
count * size_of::<T>()bytes from the source to the destination. The two regions must not overlap. - dangling
- Creates a new pointer that is dangling, but non-null and well-aligned.
- drop_
in_ ⚠place - Executes the destructor (if any) of the pointed-to value.
- eq
- Compares pointers for equality.
- from_
mut - Converts a reference to a pointer.
- from_
ref - Converts a reference to a pointer.
- hash
- Hash a pointer.
- null
- Creates a null pointer.
- read⚠
- Reads the value from the source without moving it. This leaves the memory in the source unchanged.
- read_
unaligned ⚠ - Reads the value from the source without moving it. This leaves the memory in the source unchanged.
- read_
volatile ⚠ - Performs a volatile read of the value from the source without moving it.
- replace⚠
- Moves
srcinto the pointeddst, returning the previousdstvalue. - slice_
from_ raw_ parts - Forms a raw slice from a pointer and a length.
- swap⚠
- Swaps the values at two mutable locations of the same type, without deinitializing either.
- swap_
nonoverlapping ⚠ - Swaps
count * size_of::<T>()bytes between the two regions of memory beginning atxandy. The two regions must not overlap. - with_
exposed_ provenance - Converts an address back to a pointer, picking up some previously ‘exposed’ provenance.
- without_
provenance - Creates a pointer with the given address and no provenance.
- write⚠
- Overwrites a memory location with the given value without reading or dropping the old value.
- write_
bytes ⚠ - Sets
count * size_of::<T>()bytes of memory starting at the destination toval. - write_
unaligned ⚠ - Overwrites a memory location with the given value without reading or dropping the old value.
- write_
volatile ⚠ - Performs a volatile write of a memory location with the given value without reading or dropping the old value.
Type Aliases§
- Reference
- Type alias for either
&Tor&mut T.