Aus dem Quell-Repository gerendert; Überschriften, Beispiele, Code, Tabellen, Links und Bilder bleiben erhalten.
Rust Style Formatting and Static Analysis
Based on the `rustfmt Book`, `Clippy Book`, `Edition Guide`, and `Error Code Index`.
Capability Boundaries
✅ Strengths
- Stable rustfmt configuration (edition, maxwidth, tabspaces, usefieldinit_shorthand, etc.)
- Clippy lint system — all 10 lint groups: correctness, suspicious, style, complexity, perf, pedantic, restriction, cargo, nursery, internal
clippy.tomlconfiguration (msrv, arithmetic-side, cognitive-complexity-threshold, avoid-breaking-exported-api, etc.)#[expect(...)]attribute (Rust 1.81+) for CI-enforced lint expectations- Lint
priorityordering for layered policy - Production CI lint policy (deny/warn/allow decisions per group)
- Edition migration (2015→2018→2021→2024, key changes per edition and cargo fix commands)
- Compiler error code interpretation (rustc --explain, common error codes reference table)
⚠️ Prerequisites
- Rust toolchain installed and configured
❌ Out of Scope
- Rust syntax basics → Use
rust-stableskill - Code review → Use
rust-code-reviewskill - API shape design (naming, type/trait design, module layout) and the full ~100 C- API Guidelines checklist → Use the `rust-api-design` skill. This skill only maps the ~25 C- rules that Clippy can mechanically enforce; the rest are design decisions.
When to Use
- "Format Rust code"
- "Run Clippy"
- "Migrate to a new Edition"
- "What does compiler error E0xxx mean?"
I. rustfmt Configuration
# .rustfmt.toml
max_width = 100 # Line width (default: 100)
tab_spaces = 4 # Indentation spaces
edition = "2024" # Rust edition
merge_derives = true # Merge derives
use_field_init_shorthand = true # Field initialization shorthand
use_try_shorthand = true # Use ? shorthandcargo fmt # Format all files
cargo fmt --check # Check formatting (CI usage)
cargo fmt -- --config max_width=80 # Apply specific configurationOptions such as imports_granularity, group_imports, and reorder_impl_items may still require nightly rustfmt; do not include them in default configurations that must pass stable CI.
II. Clippy
cargo clippy # Default: correctness, suspicious, style, complexity, perf
cargo clippy -- -W clippy::pedantic # Enable pedantic group
cargo clippy --fix # Auto-fix MachineApplicable lints
cargo clippy -- -A clippy::module_inception # Allow a specific lintAll 10 lint groups
| Group | Default level | Description | High-leverage lints |
|---|---|---|---|
correctness | deny (effectively) | Code that is wrong — broken semantics | almost_swap, drop_non_drop, if_same_then_else, out_of_bounds_looping, ptr_offset_with_cast |
suspicious | warn | Likely-buggy code that compiles but smells off | mutable_key_type, assign_op_pattern, blqcklisted_name, cast_lossless, clone_on_ref_ptr |
style | warn (default group) | Idiomatic Rust stylistic preferences | enum_variant_names, new_without_default, wrong_self_convention, needless_return, module_inception |
complexity | warn | Code that could be simpler | too_many_arguments, cognitive-complexity, manual_flatten, option_option |
perf | warn | Performance hints (allocations, copies) | large_enum_variant, single_char_pattern, manual_memcpy, vec_box, derivable_impls |
pedantic | allow (opt-in) | Opinionated style — stricter than style | cast_possible_truncation, fn_params_excessive_bools, must_use_candidate, missing_errors_doc, module_name_repetitions |
restriction | allow (opt-in) | Forbid patterns that may be intentional but risky | unwrap_used, expect_used, panic, indexing_slicing, dbg_macro, print_stdout, float_arithmetic |
cargo | warn | Cargo.toml quality | cargo_common_metadata, negative_feature_names, redundant_feature_names, wildcard_dependencies |
nursery | allow (experimental) | Lints under development | use_self, fallible_impl_from, missing_const_for_fn |
internal | allow | For Clippy's own development | (rarely used by users) |
#[expect] attribute (Rust 1.81+) — better than #[allow]
// ✅ #[expect] — CI fails if the lint stops firing, surfacing dead expectations
#[expect(clippy::too_many_arguments, reason = "configurable builder has many options")]
fn build(name: &str, retries: u32, timeout: u32, /* 5 more */) { /* */ }
// ❌ #[allow] — silently becomes dead code if the lint stops firing
#[allow(clippy::too_many_arguments)]
fn build(/* */) { /* */ }Prefer #[expect] for intentional suppressions; reserve #[allow] for transient reasons.
Lint priority — layering
// Higher priority wins. Use for layered policy.
#![warn(clippy::pedantic)] // enable pedantic (priority 0)
#![warn(priority = 1, clippy::module_name_repetitions)] // re-enable a specific lintclippy.toml configuration
# clippy.toml at workspace root
msrv = "1.85" # Don't suggest APIs newer than MSRV
avoid-breaking-exported-api = false # Suggest fixes that change public API
cognitive-complexity-threshold = 25 # Function complexity limit
arithmetic-side = "checked" # Prefer checked_* arithmetic
enum-variant-name-threshold = 1 # Trigger variant_name lint
single-char-binding-names-threshold = 3 # Allow `_a`, `_b`, but not 4+
too-many-arguments-threshold = 7
type-complexity-threshold = 250
disallowed-methods = [
{ path = "std::env::var", reason = "use our config::get instead" },
]
disallowed-types = [
{ path = "std::collections::LinkedList", reason = "almost never the right choice" },
]
disallowed-macros = [
{ path = "std::println", reason = "use tracing in libraries" },
]See references/clippy-lint-policy.md for the full clippy.toml reference and production policies.
Production CI lint policy
Different projects need different strictness. See references/clippy-lint-policy.md for ready-to-paste configurations.
| Project type | Pedantic | Restriction | Recommended |
|---|---|---|---|
| Library (published) | warn | allow | clippy::all + clippy::pedantic warn + cargo::cargo_common_metadata deny |
| Application / binary | warn | warn (unwrap_used) | Add restriction::unwrap_used, panic, indexing_slicing |
| Embedded / safety-critical | warn | deny | All restriction lints deny; add float_arithmetic deny |
| Internal tool | allow | allow | Just clippy::all (default groups) |
III. Edition Migration
# Check current edition
cargo metadata --format-version 1 | jq '.packages[0].edition'
# Migration steps (example: 2021 → 2024)
cargo fix --edition # Auto-migrate code
cargo build # Verify compilation
cargo test # Validate functionality
# Update Cargo.toml
# edition = "2024"Key changes per edition:
| Edition | Key Changes |
|---|---|
| 2015→2018 | Path and module import changes, dyn Trait, NLL, anonymous lifetimes and keywords changed |
| 2018→2021 | Precise closure capture, array IntoIterator, panic macro consistency, prelude and reserved syntax changes |
| 2021→2024 | RPIT lifetime capture, match ergonomics adjustment, temporary value scope, unsafe extern/unsafe attributes, gen keyword, etc. |
IV. Compiler Error Code Quick Reference
# View error details
rustc --explain E0277| Error Code | Meaning | Typical Scenario |
|---|---|---|
| E0277 | Trait not implemented | T: Trait bound is unsatisfied |
| E0308 | Type mismatch | Expected type A, but B provided |
| E0502 | Borrow conflict | Cannot have mutable borrow and immutable borrow simultaneously |
| E0597 | Insufficient lifetimes | Reference goes out of scope beyond its lifetime value |
| E0432 | Import not found | use path is incorrect |
| E0061 | Parameter count mismatch | Function call has wrong number of parameters |
| E0106 | Missing lifetimes | Function signature requires explicit lifetimes |
| E0382 | Use moved value | Ownership already transferred |
| E0499 | Simultaneous mutable borrow | Only one &mut allowed per expression |
| E0716 | Insufficient lifetime for temporary values | Reference on temporary exceeds its scope |
V. API Guidelines ↔ Clippy Lints
The Rust API Guidelines checklist uses C-* rules (about 100 total). Clippy mechanically enforces roughly 25 of them; the remaining ~75 are design judgments (naming, type/trait shape, module layout) that belong to the rust-api-design skill, or require cargo-semver-checks for breaking-change detection. The table below lists the 12 highest-leverage mappings reviewers ask about most. The full crosswalk, including "lints not yet covered" guidance, lives in `references/api-guidelines-to-clippy.md`.
| C-* Rule | Clippy Lint | Group | Effect |
|---|---|---|---|
| C-UNWRAP | clippy::unwrap_used | restriction | Flags unwrap() calls |
| C-UNWRAP | clippy::expect_used | restriction | Flags expect() calls |
| C-PANIC | clippy::panic | restriction | Flags panic!() |
| C-INDEXING | clippy::indexing_slicing | restriction | Flags [i] indexing (panics) |
| C-BOOL-ARG | clippy::fn_params_excessive_bools | pedantic | Functions with ≥3 bool params |
| C-NEWTYPE | clippy::new_without_default | style | new() exists but no Default |
| C-NEWTYPE | clippy::new_ret_no_self | style | new() returns non-Self |
| C-CONV / C-WRONG-SELF | clippy::wrong_self_convention | style | as_X(self) taking &self, or to_X(&self) consuming self |
| C-STRING-PATTERNS | clippy::single_char_pattern | perf | .contains("a") → .contains('a') |
| C-COMMON-TRAITS | clippy::derivable_impls | perf | Manual impl that could be derived |
| C-LARGE-NUMERIC | clippy::unreadable_literal | style | 1000000 should be 1_000_000 |
| C-MUTABLE-KEY | clippy::mutable_key_type | suspicious | HashMap key type is mutable |
| C-CLONE-ON-REF | clippy::clone_on_ref_ptr | restriction | .clone() on Rc/Arc |
Many restriction and pedantic lints are off by default — enable them explicitly via #![warn(clippy::unwrap_used)] or in clippy.toml when enforcing a guideline in CI.
Workflow
- Format code —
cargo fmtensures consistent style - Run Clippy —
cargo clippyruns the 5 default groups (correctness, suspicious, style, complexity, perf); add-W clippy::pedanticfor stricter - Decide policy — pick pedantic/restriction level by project type (see table above); paste the matching config from
references/clippy-lint-policy.md - Configure
clippy.toml— setmsrv,disallowed-methods, and any project-specific thresholds - Use
#[expect]for intentional suppressions — keeps CI honest about dead expectations - Check Edition — Confirm edition in Cargo.toml is up-to-date
- CI integration —
cargo fmt --check+cargo clippy -- -D warnings+cargo auditin CI
Gotchas
cargo clippy --fixonly fixes lints at MachineApplicable level- rustfmt config file is named
.rustfmt.toml, notrustfmt.toml - After edition migration, new warnings may appear — especially around unsafeopinunsafefn in 2024
cargo fix --editiondoes not fix all issues; manual review required after migration- Prefer
let ... elsefor early exits andis_some_and/then_somefor simple boolean mapping; avoid compressing complex control flows just to use modern syntax saturating_*,checked_*, and regular arithmetic expressions have different business semantics regarding overflow strategy — decide first, then select API
On-Demand Resources
- Format and Clippy Examples
- Lint Group Quick Reference
- Clippy Lint Policy: Full
clippy.tomlreference, all 10 lint groups in depth,#[expect]patterns,prioritylayering, and ready-to-paste production CI configurations by project type. - Production Rust Idioms: Review let-else, Option combinators, newtype patterns, non-exhaustive APIs, lock scopes, and overflow strategies when reviewing production code.
- API Guidelines ↔ Clippy Lints Crosswalk: Full mapping from Rust API Guidelines
C-*rules to the Clippy lints that enforce them, plus the ~75 rules Clippy does not cover and where to review them. examples/golden-style/: Golden examples for CI passing rustfmt and Clippy

