Expand description
Checkers for the Send/Sync marker-trait predicates.
These are intentionally structural/behavioural approximations (sound-incomplete): a full proof of “exclusive ownership” / “no cross-thread aliasing” needs an ownership + concurrency model (e.g. separation logic), which the current sequential VM does not have.
The vocabulary follows the Rust model: a raw pointer is !Send unless
tamed — either the type has no raw pointers at all ([NoRawPtr]), or its
raw-pointer field is Allocated/Owning (discharged via the struct’s
#[rapx::invariant] annotations) and updated read-only ([NoInternalMut]),
exclusively ([UniInternalMut]), or under synchronization / atomically
([AtomicUpdate]). The composition is declared in
std-trait-ensures.json + std-compound-properties.rs; this module only
implements the primitive type-level checks.
Enums§
- Contains 🔒
- Three-valued structural verdict: a type definitely contains a negative
(
Yes), definitely does not (No), or contains an unresolved generic parameter so the answer is unknown (Maybe).
Functions§
- atomic_
update_ 🔒check - Type-level
AtomicUpdateobligation check (no VM state required):Provedwhen aliased updates of the type’s raw pointers are safe without exclusive ownership. Two ways satisfy this: - contain_
no_ 🔒type_ check - Type-level
ContainNoTypeobligation check (no VM state required): returnsFailediftystructurally contains any named negative,Unknownif a generic parameter makes the answer unresolved, elseProved. - field_
invariant_ 🔒check - Type-level
Allocated(ptr, T, n)/Owning(ptr)obligation check (no VM state required):ProvedwhenTdeclares a matching#[rapx::invariant(Allocated(ptr))]/#[rapx::invariant(Owning(ptr))]annotation (optionally restricted to thefieldnamed in the property) and the already-run struct-invariant verification discharged it.invariant_resultscarries the per-struct verdict; when a struct’s invariants failed to verify, the check fails too. - find_
raw_ 🔒ptr - Structurally check whether
ty(transitively) contains a raw pointer. A raw pointer may also appear as a pattern type (pattern_type!(*const T is ..)), so recurse intoTyKind::Pat. - find_
unsynchronized_ 🔒mutation - Find an interior-mutability / raw-pointer field that is not guarded by a
synchronization primitive. A raw pointer may also appear as a pattern type
(
pattern_type!(*const T is ..)), so recurse intoTyKind::Pat. - has_
atomic_ 🔒ptr_ updates - Whether any inherent method of
typerforms an atomic update through an atomic intrinsic or anAtomic*method (fetch_add/store/…), e.g. anArc-stylefetch_addon a reference count reached via a raw pointer. - has_
raw_ 🔒ptr_ writes - Whether any inherent method of
tywrites through a raw pointer. - no_
internal_ 🔒mut_ check - Type-level
NoInternalMutobligation check (no VM state required):Failedif any inherent method writes through a raw pointer — either a plain*ptr = ...write or an atomic update (Atomic*intrinsic). - no_
raw_ 🔒ptr_ check - Type-level
NoRawPtrobligation check (no VM state required). - param_
bound_ 🔒is_ satisfied - Whether a generic type parameter carries a
Send/Syncbound on the impl, letting the checker treat it as satisfied instead ofUnknown. - ref_
send_ 🔒check - Type-level
RefSendobligation check (no VM state required). - type_
implements_ 🔒clone - Whether
tyimplementsClone(which copies any raw-pointer field, aliasing the pointee across a move). - type_
structurally_ 🔒contains - Structurally check whether
ty(transitively) contains one of the negative types identified bynegative_defs. A synchronization primitive (Mutex/RwLock/Atomic*) guards its interior, so the scan stops there — a negative type nested inside one (e.g.Mutex<UnsafeCell>) is considered tamed. - uni_
internal_ 🔒mut_ check - Type-level
UniInternalMutobligation check (no VM state required):Provedif the type writes through a raw pointer (plain or atomic) but does not implementClone(which would copy the pointer and alias the pointee).