Contributing to Surelock #
Prerequisites #
This project uses Nix for reproducible development environments.
nix develop
menu # list available commands
Building #
cargo build
cargo build --all-features
cargo build --no-default-features # no_std check
Testing #
cargo test # all tests (unit, integration, doc, property, compile-fail)
cargo test --doc # doc tests only
cargo test --test integration # integration tests only
cargo test --test property # property tests (bolero)
cargo test --test compile_fail # compile-fail tests (trybuild)
Linting #
cargo clippy --all-targets
cargo clippy --all-targets --all-features
cargo fmt --check
cargo doc # check for doc warnings
Project Structure #
src/
├── acquirable.rs Acquirable<'a> trait (internal)
├── acquirable/tuples.rs Tuple impls 2-12
├── id.rs LockId
├── key.rs MutexKey, lock_scope, try_lock_scope
├── key_handle.rs KeyHandle
├── key_voucher.rs KeyVoucher
├── level.rs Level<N>, IsLevel, LockAfter, etc.
├── locksmith.rs Locksmith
├── mutex.rs Mutex<T, Lvl, R>
├── mutex/guard.rs MutexGuard
├── raw_mutex.rs RawMutex trait
├── raw_mutex/std_mutex.rs StdMutex backend
├── raw_mutex/lock_api_adapter.rs lock_api bridge
└── set.rs LockSet
tests/
├── integration.rs Full lifecycle tests
├── lock_order.rs Level declaration tests
├── compile_fail.rs Compile-fail test runner
├── compile_fail/*.rs Individual compile-fail cases
└── property.rs Property tests (bolero)
design/ Published design docs
├── README.md Architecture overview
├── ROADMAP.md Planned features for v2+
└── comparison/ Comparisons with prior art
.ignore/ Internal design notes (gitignored, not published)
├── CONTEXT.md Codebase overview
├── DESIGN.md Architecture reference
├── DECISIONS.md ADRs (Architecture Decision Records)
├── ALTERNATIVES.md Approaches considered
├── TODO.md Task list
└── CRITICAL_SECTION_BACKEND.md no_std backend sketch
Unsafe Policy #
#![deny(unsafe_code)] at the crate level. Only modules that
need unsafe opt in via #![allow(unsafe_code)]:
raw_mutex.rs--unsafe trait RawMutexraw_mutex/std_mutex.rs--unsafe implfor StdMutexraw_mutex/lock_api_adapter.rs-- blanketunsafe implmutex.rs--unsafe impl Send/Syncmutex/guard.rs--Deref/DerefMutonUnsafeCellkey_voucher.rs--unsafe impl Send
All other modules are fully safe. Adding unsafe to a new module
requires justification.
Naming Conventions #
| Type | Name | Variable |
|---|---|---|
| Factory | Locksmith |
smith |
| Voucher | KeyVoucher |
voucher |
| Per-thread | KeyHandle |
handle |
| Scope key | MutexKey |
key |
| Guard | MutexGuard |
guard |
| Lock group | Acquirable |
-- |
| Pre-sorted | LockSet |
set |
Adding a New Level Trait #
Level impls are generated by macros in src/level.rs. To change
the default count or add a new trait to the level system:
- Update the
generate_level_impls!macro - Update the
#[cfg]blocks for feature-gated counts - Run
cargo test-- property tests verify level ordering invariants
Adding a New Tuple Arity #
Tuple Acquirable impls are in src/acquirable/tuples.rs. The
2-tuple supports multi-level (different Lvl per element); arities
3-12 require same level. To add a multi-level impl for higher
arities, see the 2-tuple impl as a reference.
Compile-Fail Tests #
Compile-fail tests use trybuild. Each test case is a .rs file in
tests/compile_fail/ with a corresponding .stderr file. To update
expected output after a change:
TRYBUILD=overwrite cargo test --test compile_fail
Design Documents #
Published design docs live in design/:
design/README.md-- architecture overview and design principlesdesign/ROADMAP.md-- planned features for v2+design/comparison/-- detailed comparisons withhappylockandlock_tree
Internal design notes live in .ignore/ (gitignored, not published):
DECISIONS.md-- numbered ADRs with rationaleDESIGN.md-- architecture referenceTODO.md-- task list with checkbox notation
When making design decisions, add an ADR to .ignore/DECISIONS.md.