Linting & Formatting Best Practices
Low-friction, high-signal quality gates keep Rust codebases consistent without debate-driven review churn.
How to Use This List
- Adopt when bootstrapping CI or after fmt/clippy fire drills on main.
- Pair with Pre-commit & Editor Setup for local parity.
- Treat each
allowas technical debt with an owner.
A - Formatting
-
cargo fmt --all --checkin CI. Zero manual style review. -
rustfmt.tomlat workspace root withedition = "2024". Matches Cargo edition. - Format on save via rust-analyzer. Same rules as CI.
- Unix newlines in rustfmt for cross-platform repos. Avoids snapshot/CI drift.
- No
#[rustfmt::skip]without comment. Rare FFI/layout exceptions only.
B - Clippy
-
cargo clippy --workspace --all-targets -- -D warningson PRs. Tests and benches included. - Optional
--all-featuresmatrix job. Cfg-gated code linted. -
clippy.tomldocuments disallowed APIs. e.g. ban rawstd::env::varin apps. - Per-crate
[lints.clippy]for apps vs libs. Stricterunwrap_useddeny in binaries. - Review
cargo clippy --fixdiffs. No blind auto-fix merges.
C - Documentation Lints
-
missing_docs = "warn"on published library crates. Ratchet to deny over time. -
RUSTDOCFLAGS="-D warnings"in doc CI job. Broken intra-doc links fail build. - Doctests run in CI for public APIs.
cargo test --doc --workspace. -
# Errors/# Safetysections on fallible and unsafe API. API guidelines compliance. - Crate-level
//!docs on every lib root. crates.io and docs.rs presentation.
D - Toolchain and CI
-
rust-toolchain.tomlpins 1.97.0 + rustfmt + clippy components. Local/CI parity. - Lint job runs before or parallel to tests, not after. Fast failure on style.
-
Swatinem/rust-cacheor equivalent. Sub-5-minute lint jobs on warm cache. - MSRV check job uses
rust-versionfrom manifest. Not only latest stable. - pre-commit hooks mirror CI fmt/clippy subset. Optional but recommended.
E - Exceptions and Policy
- Line-level
#[allow(clippy::...)]with reason comment. No file-level blanket allows. -
forbid(unsafe_code)on domain crates; single FFI crate exempt. Documented in ARCHITECTURE. - Lint policy in CONTRIBUTING.md. New hires know expectations day one.
- Revisit allows on toolchain upgrade. New lints may replace custom allows.
- No debating style in PR comments. Point to rustfmt/clippy output instead.
FAQs
Minimum CI for small project?
fmt --check + clippy -D warnings + test on stable 1.97.0.
Pedantic clippy default?
Start with default clippy; enable pedantic on new crates if team wants stricter idioms.
How handle legacy crate?
Warn-level lints with ratchet; fix files touched per PR rule.
deny warnings on beta?
Optional preview; main gate stays on pinned stable.
Who owns clippy.toml?
Platform team or tech lead; changes via PR with team notice.
fmt before or after merge conflict?
Always run cargo fmt after resolving conflicts.
Lint generated code?
Exclude from rustfmt/clippy via ignore paths; never hand-edit generated sources.
How measure lint ROI?
Fewer style comments in review; faster CI green rate; clippy catches in postmortems decline.
Combine with cargo-deny?
Separate job: licenses, advisories, duplicate deps - complements clippy.
IDE without clippy?
Developers still get CI feedback; strongly recommend check.command = clippy in settings.
Related
- rustfmt - formatting
- Clippy - lint catalog
- Linting in CI - pipelines
- 50 Rust Rules - style rules
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.