# Cargo Strict Configuration

The exact knobs every new Rust project gets. Drop these in unmodified.

## `rust-toolchain.toml`

```toml
[toolchain]
channel = "stable"
components = ["rustfmt", "clippy", "rust-src"]
profile = "default"
```

Pin nightly separately when miri runs:

```bash
rustup install nightly
rustup component add miri rust-src --toolchain nightly
```

## `Cargo.toml` — `[lints]` section

```toml
[lints.rust]
unsafe_op_in_unsafe_fn = "deny"
missing_docs = "warn"
missing_debug_implementations = "warn"
unreachable_pub = "warn"
unused_must_use = "deny"
elided_lifetimes_in_paths = "warn"
non_ascii_idents = "deny"
trivial_numeric_casts = "warn"
unused_lifetimes = "warn"
single_use_lifetimes = "warn"
# every custom cfg is declared here; a typo like cfg(feture = "x") fails the build
unexpected_cfgs = { level = "deny", check-cfg = ["cfg(loom)"] }

[lints.clippy]
# Groups
all = { level = "deny", priority = -1 }
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }

# Hard denies - turn warnings into errors for sharp tools
undocumented_unsafe_blocks = "deny"
multiple_unsafe_ops_per_block = "deny"
unwrap_used = "deny"
expect_used = "deny"
panic = "deny"
todo = "deny"
unimplemented = "deny"
unreachable = "deny"
indexing_slicing = "deny"
mem_forget = "deny"
arithmetic_side_effects = "warn"
cast_possible_truncation = "warn"
cast_possible_wrap = "warn"
cast_precision_loss = "warn"
cast_sign_loss = "warn"
as_underscore = "deny"
as_ptr_cast_mut = "deny"
ptr_as_ptr = "warn"
borrow_as_ptr = "warn"
fn_to_numeric_cast_any = "deny"
clone_on_ref_ptr = "warn"
mutex_atomic = "warn"
rc_buffer = "warn"
rc_mutex = "warn"
exit = "warn"
allow_attributes = "deny"                 # silence with #[expect(lint, reason)], never #[allow]
allow_attributes_without_reason = "deny"
let_underscore_must_use = "deny"          # `let _ = fallible()` drops the error
dbg_macro = "warn"
print_stderr = "warn"
print_stdout = "warn"
use_debug = "warn"

# Stylistic relaxations (project-wide opinions only)
module_name_repetitions = "allow"
must_use_candidate = "allow"

# Restriction lints - opt-in soundness rails
mod_module_files = "warn"      # prefer foo.rs over foo/mod.rs
empty_drop = "warn"
empty_structs_with_brackets = "warn"
empty_enum = "warn"
exhaustive_enums = "warn"      # public enums should consider #[non_exhaustive]
exhaustive_structs = "warn"
```

The `priority = -1` trick: group-level levels are weak; specific lints below them win. This lets us deny `unwrap_used` while still allowing `pedantic` group warnings instead of denies.

A lint is silenced only with `#[expect(clippy::lint_name, reason = "...")]` on the smallest item that needs it. Unlike `#[allow]`, `#[expect]` fails the build once the lint stops firing, so stale exceptions cannot pile up; `allow_attributes` and `allow_attributes_without_reason` enforce both halves. `missing_errors_doc` / `missing_panics_doc` stay on (pedantic): public fallible APIs document their `# Errors`.

## `Cargo.toml` — release profile

```toml
[profile.release]
opt-level = 3
lto = "fat"
codegen-units = 1
strip = "symbols"
panic = "abort"        # smaller, faster - if you need unwinding (FFI catch), set "unwind"
debug = "line-tables-only"

[profile.dev]
opt-level = 0
debug = true
incremental = true
codegen-units = 256
split-debuginfo = "unpacked"

# A profile for miri - opt-level 1 keeps simulation bearable while still
# exercising real codegen patterns. miri ignores most profile keys but reads
# overflow-checks.
[profile.miri]
inherits = "test"
opt-level = 1
overflow-checks = true
```

`-C target-cpu=native` and PGO are deployment decisions, not defaults: a `native` binary faults on older CPUs, and PGO only pays with a representative training workload. Apply either only with a before/after measurement.

## `Cargo.toml` — workspace level

```toml
[workspace]
resolver = "3"

[workspace.package]
edition = "2024"
rust-version = "1.85"   # the 2024 edition floor; raise only when a needed feature lands
license = "Apache-2.0 OR MIT"

[workspace.lints]
# Then in each member crate:
# [lints]
# workspace = true

[workspace.dependencies]
# one version per dependency; members write `serde = { workspace = true }`
```

## Features and build scripts

- **Features are additive.** Enabling a feature never removes an API or changes another feature's behavior, and `--all-features` always builds. Optional dependencies use `dep:` (`serde = ["dep:serde"]`) so no implicit feature leaks. Truly exclusive backends fail loudly: `#[cfg(all(feature = "a", feature = "b"))] compile_error!("features `a` and `b` are mutually exclusive");`.
- **`build.rs` is deterministic.** Declare every input with `cargo::rerun-if-changed=` / `cargo::rerun-if-env-changed=`, write only under `OUT_DIR`, and never touch the network. A build script that reads undeclared inputs produces stale builds that pass locally and fail in CI.

## `rustfmt.toml`

```toml
edition = "2024"
max_width = 100
imports_granularity = "Module"
group_imports = "StdExternalCrate"
reorder_imports = true
reorder_modules = true
newline_style = "Unix"
use_field_init_shorthand = true
use_try_shorthand = true
unstable_features = false
```

Most options come from stable rustfmt. `imports_granularity` and `group_imports` are nightly-only but ignored cleanly on stable; CI runs `cargo +nightly fmt --check` for the import grouping.

## `clippy.toml`

```toml
# Reduce cognitive load thresholds.
cognitive-complexity-threshold = 25
type-complexity-threshold = 250
too-many-arguments-threshold = 3   # SKILL.md Smell 2: more than 3 parameters is a smell
too-many-lines-threshold = 100

# msrv - keeps clippy from suggesting features past our MSRV
msrv = "1.85"

# Avoid `panic` lint complaining about derived Debug impls calling unreachable_unchecked etc.
allow-unwrap-in-tests = true
allow-expect-in-tests = true
allow-panic-in-tests = true
allow-dbg-in-tests = true
allow-print-in-tests = true

# At most 4 single-character bindings in scope
single-char-binding-names-threshold = 4
```

## `deny.toml` (cargo-deny)

```toml
[advisories]
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
yanked = "deny"
ignore = []

[licenses]
allow = [
    "MIT",
    "Apache-2.0",
    "Apache-2.0 WITH LLVM-exception",
    "BSD-2-Clause",
    "BSD-3-Clause",
    "ISC",
    "Unicode-DFS-2016",
    "Unicode-3.0",
    "Zlib",
    "MPL-2.0",
    "CC0-1.0",
]
confidence-threshold = 0.93
exceptions = []

[bans]
multiple-versions = "warn"
wildcards = "deny"
highlight = "all"
deny = [
    # Pin out unmaintained alternatives
    { name = "async-std", reason = "use tokio" },
    { name = "actix-web", reason = "use axum" },
    { name = "chrono", reason = "use jiff" },
]

[sources]
unknown-registry = "deny"
unknown-git = "warn"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
```

## CI Workflow (`.github/workflows/ci.yml`)

```yaml
name: ci
on:
  push:
    branches: [main]
  pull_request:

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  fmt:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: rustfmt
      - run: cargo +nightly fmt --all -- --check

  clippy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2
      - run: cargo clippy --all-targets --all-features --workspace -- -D warnings

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - uses: taiki-e/install-action@nextest
      - run: cargo nextest run --all-targets --all-features --workspace
      - run: cargo test --doc --all-features --workspace   # nextest does not run doctests

  doc:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - env:
          RUSTDOCFLAGS: "-D warnings"   # broken intra-doc links fail the build
        run: cargo doc --no-deps --all-features --workspace

  msrv:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@1.85   # = rust-version
      - uses: Swatinem/rust-cache@v2
      - run: cargo check --all-features --workspace

  miri:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
        with:
          components: miri, rust-src
      - uses: Swatinem/rust-cache@v2
      - uses: taiki-e/install-action@nextest
      - env:
          MIRIFLAGS: "-Zmiri-strict-provenance -Zmiri-symbolic-alignment-check"
        run: cargo +nightly miri nextest run --all-features --workspace
      - env:
          MIRIFLAGS: "-Zmiri-tree-borrows -Zmiri-strict-provenance -Zmiri-symbolic-alignment-check"
        run: cargo +nightly miri nextest run --all-features --workspace

  machete:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: bnjbvr/cargo-machete@main

  deny:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: EmbarkStudios/cargo-deny-action@v2
        with:
          command: check all

  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: rustsec/audit-check@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
```

## Project bootstrap

```bash
cargo new --bin my-app --edition 2024
cd my-app
cargo install cargo-nextest cargo-machete cargo-deny cargo-edit cargo-watch
rustup install nightly
rustup component add miri --toolchain nightly
# drop the configs above
git add . && git commit -m "chore: bootstrap strict toolchain"
```

After every change:

```bash
cargo fmt --all -- --check && \
cargo clippy --all-targets --all-features -- -D warnings && \
cargo nextest run && cargo test --doc && \
cargo +nightly miri nextest run    # only if unsafe is involved
```
