SKILL.md
Rust Unsafe Boundaries
Use this skill to isolate unsafe Rust behind small, documented, testable boundaries. Unsafe code is acceptable only when a safe API cannot express the needed operation with acceptable correctness and performance.
Core Workflow
- Try the safe design first. Check standard APIs, ownership restructuring,
iterators, synchronization primitives, and existing crates.
- State the invariant that safe Rust cannot prove. If the invariant cannot be
written down, do not write unsafe code yet.
- Keep unsafe blocks tiny. Put runtime checks and setup in safe code before the
block.
- Add a
// SAFETY: comment immediately before each unsafe block explaining
why every unsafe operation inside is valid.
- Mark a function
unsafe fn only when callers must uphold extra conditions.
Document those conditions in a # Safety section.
- Enable or respect
unsafeopinunsafefn; unsafe operations inside unsafe
functions should still be wrapped in explicit unsafe blocks.
- Test normal behavior, boundary cases, panic paths, and drop behavior. Run
Miri when the project supports it.
Boundary Rules
Read references/safety-invariants.md before adding or approving unsafe code.
- Prefer private unsafe internals plus a safe public wrapper.
- Prefer
MaybeUninit<T> over deprecated or ad hoc uninitialized memory
patterns.
- Never create references from raw pointers unless validity, alignment,
initialization, aliasing, and lifetime are all proven.
- Do not use
setlen, pointer arithmetic, or fromraw_parts without proving
capacity, initialization, and ownership.
- Make panic safety explicit when partially initialized values, manual drops, or
length changes are involved.
- Avoid
static mut; prefer OnceLock, LazyLock, atomics, or locked state.
Documentation Pattern
/// # Safety
///
/// `ptr` must be non-null, aligned for `T`, initialized, and valid for reads
/// for the returned lifetime. No mutable reference may alias the same value.
pub unsafe fn read_ref<'a, T>(ptr: *const T) -> &'a T {
// SAFETY: The caller guarantees `ptr` satisfies the documented contract.
unsafe { &*ptr }
}
Review Checklist
- Every unsafe block has a local
SAFETY explanation.
- Every
unsafe fn or unsafe trait has a # Safety contract.
- Public safe APIs cannot be used to violate internal invariants.
- Drop, panic, and early-return paths preserve initialization and ownership.
- Tests or Miri cover the dangerous edge, not only the happy path.