about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAria Beingessner <a.beingessner@gmail.com>2022-03-27 15:06:06 -0400
committerAria Beingessner <a.beingessner@gmail.com>2022-03-29 20:18:27 -0400
commit9efcd996d528b7da9beb0a9743b6659c667154d6 (patch)
tree93df5e7e042af059f88e1ec4c067365bf41de5ef
parent7514d760b8fabd46e4874520b653ab8803c3517e (diff)
downloadrust-9efcd996d528b7da9beb0a9743b6659c667154d6.tar.gz
rust-9efcd996d528b7da9beb0a9743b6659c667154d6.zip
Add even more details to top-level pointer docs
-rw-r--r--library/core/src/ptr/mod.rs24
1 files changed, 20 insertions, 4 deletions
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 6d04add67d1..d988edb213e 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -153,8 +153,8 @@
 //! integers is very useful, so what can we do?
 //!
 //! Strict Provenance attempts to square this circle by decoupling Rust's traditional conflation
-//! of pointers and `usize` (and `isize`), defining a pointer to semantically contain the following
-//! information:
+//! of pointers and `usize` (and `isize`), and defining a pointer to semantically contain the
+//! following information:
 //!
 //! * The **address-space** it is part of.
 //! * The **address** it points to, which can be represented by a `usize`.
@@ -235,6 +235,10 @@
 //! }
 //! ```
 //!
+//! (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,
+//! we would like to know why, and what needs to be done to fix it.)
+//!
 //! Something more complicated and just generally *evil* like a XOR-List requires more significant
 //! changes like allocating all nodes in a pre-allocated Vec or Arena and using a pointer
 //! to the whole allocation to reconstitute the XORed addresses.
@@ -258,11 +262,13 @@
 //!
 //! * Create an invalid pointer from just an address (see [`ptr::invalid`][]). This can
 //!   be used for sentinel values like `null` *or* to represent a tagged pointer that will
-//!   never be dereferencable.
+//!   never be dereferencable. In general, it is always sound for an integer to pretend
+//!   to be a pointer "for fun" as long as you don't use operations on it which require
+//!   it to be valid (offset, read, write, etc).
 //!
 //! * Forge an allocation of size zero at any sufficiently aligned non-null address.
 //!   i.e. the usual "ZSTs are fake, do what you want" rules apply *but* this only applies
-//!   for actual forgery (integers cast to pointers). If you borrow some structs subfield
+//!   for actual forgery (integers cast to pointers). If you borrow some struct's field
 //!   that *happens* to be zero-sized, the resulting pointer will have provenance tied to
 //!   that allocation and it will still get invalidated if the allocation gets deallocated.
 //!   In the future we may introduce an API to make such a forged allocation explicit.
@@ -277,6 +283,16 @@
 //!   and based on alignment, but the buffer on either side of the pointer's range is pretty
 //!   generous (think kilobytes, not bytes).
 //!
+//! * Compare arbitrary pointers by address. Addresses *are* just integers and so there is
+//!   always a coherent answer, even if the pointers are invalid or from different
+//!   address-spaces/provenances. Of course, comparing addresses from different address-spaces
+//!   is generally going to be *meaningless*, but so is comparing Kilograms to Meters, and Rust
+//!   doesn't prevent that either. Similarly, if you get "lucky" and notice that a pointer
+//!   one-past-the-end is the "same" address as the start of an unrelated allocation, anything
+//!   you do with that fact is *probably* going to be gibberish. The scope of that gibberish
+//!   is kept under control by the fact that the two pointers *still* aren't allowed to access
+//!   the other's allocation (bytes), because they still have different provenance.
+//!
 //! * Perform pointer tagging tricks. This falls out of [`wrapping_offset`] but is worth
 //!   mentioning in more detail because of the limitations of [CHERI][]. Low-bit tagging
 //!   is very robust, and often doesn't even go out of bounds because types have a