Skip to content

Commit 2bf955a

Browse files
committed
[pointer] Document validity safety invariant
Document the semantics of `Ptr` validity invariants on the `Validity` trait. TODO: - [ ] Prove that this safety invariant is upheld at all transmute sites - [ ] Consume this safety invariant wherever it's relevant Makes progress on #2226, #1866 gherrit-pr-id: Ie66db9044be1dc310a6b7280a73652a357878376
1 parent dccbbcd commit 2bf955a

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

src/pointer/invariant.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,45 @@ pub trait Aliasing: Sealed {
4242
pub trait Alignment: Sealed {}
4343

4444
/// The validity invariant of a [`Ptr`][super::Ptr].
45+
///
46+
/// # Safety
47+
///
48+
/// In this section, we will use `Ptr<T, V>` as a shorthand for `Ptr<T, I:
49+
/// Invariants<Validity = V>>` for brevity.
50+
///
51+
/// Each `V: Validity` defines a set of bit values which may appear in the
52+
/// referent of a `Ptr<T, V>`. Each `V: Validity`, in its documentation,
53+
/// provides a definition of this set in terms of any referent type (in other
54+
/// words, this definition holds for all `T: ?Sized`).
55+
///
56+
/// Let `S(T, V)` be the set of bit values permitted to appear in the referent
57+
/// of a `ptr: Ptr<T, V>` (as defined by and documented on `V`). It is
58+
/// guaranteed that the referent of `ptr` is a member of `S(T, V)`. Unsafe code
59+
/// producing a `Ptr<T, V>` must ensure that this guarantee will be upheld.
60+
///
61+
/// An important implication of this guarantee is that it restricts what
62+
/// transmutes are sound, where "transmute" is used in this context to refer to
63+
/// changing the referent type or validity invariant of a `Ptr`, as either
64+
/// change may change the set of bit values permitted to appear in the referent.
65+
/// In particular, the following are necessary (but not sufficient) conditions
66+
/// in order for a transmute from `src: Ptr<T, V>` to `dst: Ptr<U, W>` to be
67+
/// sound:
68+
/// - If `S(T, V) = S(U, W)`, then no restrictions apply; otherwise,
69+
/// - If `dst` permits mutation of its referent (e.g. via `Exclusive` aliasing
70+
/// or interior mutation under `Shared` aliasing), then it must hold that
71+
/// `S(T, V) ⊇ S(U, W)` - in other words, the transmute must not expand the
72+
/// set of allowed referent bit patterns. A violation of this requirement
73+
/// would permit using `dst` to write `x` where `x ∈ S(U, W)` but `x ∉ S(T,
74+
/// V)`, which would violate the guarantee that `src`'s referent may only
75+
/// contain values in `S(T, V)`.
76+
/// - If the referent may be mutated without going through `dst` while `dst` is
77+
/// live (e.g. via interior mutation on a `Shared`-aliased `Ptr` or `&`
78+
/// reference), then it must hold that `S(T, V) ⊆ S(U, W)` - in other words,
79+
/// the transmute must not shrink the set of allowed referent bit patterns. A
80+
/// violation of this requirement would permit using `src` or another
81+
/// mechanism (e.g. a `&` reference used to derive `src`) to write `x` where
82+
/// `x ∈ S(T, V)` but `x ∉ S(U, W)`, which would violate the guarantee that
83+
/// `dst`'s referent may only contain values in `S(U, W)`.
4584
pub trait Validity: Sealed {}
4685

4786
/// An [`Aliasing`] invariant which is either [`Shared`] or [`Exclusive`].

0 commit comments

Comments
 (0)