🦀🔐 Statically prevent deadlocks crates.io/crates/surelock
typesafe utility deadlock-freedom library
surelock HACKING.md
4.9 kB
Markdown
at main

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 RawMutex
  • raw_mutex/std_mutex.rs -- unsafe impl for StdMutex
  • raw_mutex/lock_api_adapter.rs -- blanket unsafe impl
  • mutex.rs -- unsafe impl Send/Sync
  • mutex/guard.rs -- Deref/DerefMut on UnsafeCell
  • key_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:

  1. Update the generate_level_impls! macro
  2. Update the #[cfg] blocks for feature-gated counts
  3. 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 principles
  • design/ROADMAP.md -- planned features for v2+
  • design/comparison/ -- detailed comparisons with happylock and lock_tree

Internal design notes live in .ignore/ (gitignored, not published):

  • DECISIONS.md -- numbered ADRs with rationale
  • DESIGN.md -- architecture reference
  • TODO.md -- task list with checkbox notation

When making design decisions, add an ADR to .ignore/DECISIONS.md.