| name | rust-lint-config |
| description | Rust clippy, rustfmt, cargo-deny configuration, new lints, and lint failure triage. |
Rust Lint Configuration
All lint configuration is centralized at the workspace level. Individual crates inherit via [lints] workspace = true -- never add per-crate lint overrides.
Configuration Files
| File | Purpose |
|---|
native/rust/Cargo.toml | [workspace.lints.clippy] and [workspace.lints.rust] -- lint levels |
native/rust/clippy.toml | Clippy thresholds and disallowed methods |
native/rust/rustfmt.toml | Formatting rules |
native/rust/deny.toml | License, advisory, and dependency checks |
Current Lint Levels
Workspace Cargo.toml [workspace.lints.clippy]
Denied (errors):
correctness -- logic errors that are almost certainly bugs
suspicious -- code that is likely wrong
Warned:
style, complexity, perf -- broad lint groups
- Cherry-picked pedantic lints:
cloned_instead_of_copied, explicit_iter_loop, explicit_into_iter_loop, implicit_clone, inefficient_to_string, map_unwrap_or, redundant_closure_for_method_calls, semicolon_if_nothing_returned, uninlined_format_args, unnested_or_patterns, manual_let_else, trivially_copy_pass_by_ref, unused_self, default_trait_access, match_wildcard_for_single_variants
Allowed (JNI/FFI exceptions):
missing_safety_doc -- JNI crates have many trivially-safe extern fns
not_unsafe_ptr_arg_deref -- required by JNI function signatures
Workspace Cargo.toml [workspace.lints.rust]
unsafe_op_in_unsafe_fn = "warn" -- require explicit unsafe blocks inside unsafe fn
clippy.toml
too-many-arguments-threshold = 8
type-complexity-threshold = 300
disallowed-methods = [
{ path = "std::iter::Iterator::for_each", reason = "Use a `for` loop for side effects (F-COMBINATOR)" },
]
rustfmt.toml
edition = "2021"
max_width = 120
use_small_heuristics = "Max"
deny.toml
- Licenses: allow-list (MIT, Apache-2.0, BSD-2/3-Clause, ISC, 0BSD, Zlib, CDLA-Permissive-2.0, Unicode-3.0, OpenSSL)
- Advisories: deny all except one explicit ignore (
RUSTSEC-2024-0436 — paste proc-macro, no runtime risk)
- Bans:
multiple-versions = "warn", wildcards = "warn"
- Sources: only crates.io registry allowed
Recommended escalations (2026-04)
The current configuration is intentionally permissive — it prioritizes shipping velocity over strict enforcement. Three escalations are ready to land once the cleanup work they gate has happened:
1. multiple-versions = "warn" → "deny"
Current state allows duplicate dep versions to silently accumulate. This masks transitive-dep drift and complicates supply-chain audits. Precondition for escalation: run cargo tree --locked --duplicates inside native/rust, resolve all existing duplicates (typically by patching workspace dep versions or adding [patch.crates-io] entries), then flip the level. Do not flip the level before the duplicates are clean — the first CI run will explode.
2. Add clippy::expect_used and clippy::unwrap_used at "warn"
Production .rs files contain ~1,727 .unwrap() / .expect() call sites as of 2026-04-17 (see rust-panic-safety skill for the full policy). Landing these lints at warn forces new code to justify each .unwrap() while leaving the existing sites compiling. Precondition: confirm every new usage in a PR gets a #[allow(clippy::unwrap_used)] // Infallible: … comment, not a workspace-wide allow.
Suggested addition to [workspace.lints.clippy]:
unwrap_used = "warn"
expect_used = "warn"
Exempt test code via #[cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))] on the test module.
3. Lower type-complexity-threshold
300 is far above Clippy's default (250) and masks genuinely unreadable types — nested HashMap<_, Arc<Mutex<HashMap<_, _>>>> style. Target 250 as a first step; lower to the default 100 only after the workspace compiles cleanly at 200. Each step reveals a different tier of type-complexity smells.
Running Lints
Local (fast iteration)
cd native/rust
cargo clippy --locked --workspace --all-targets -- -D warnings
cargo fmt --all -- --check
cargo deny --locked check
cargo clippy --locked --workspace --all-targets -- -D warnings && cargo fmt --all -- --check && cargo deny --locked check
CI
The .github/workflows/ci.yml pipeline runs these as separate steps. Clippy and fmt run on every push/PR to main.
Single-crate iteration
cargo clippy --locked -p ripdpi-monitor-engine --all-targets -- -D warnings
Adding a New Lint
- Add the lint to
[workspace.lints.clippy] in native/rust/Cargo.toml
- Run
cargo clippy --locked --workspace --all-targets to find all violations
- Fix violations across the workspace. If too numerous for one patch:
- Add
#[allow(clippy::lint_name)] with a // TODO(po4yka): fix comment on individual sites
- Create a follow-up task to clean them up
- Never suppress a lint workspace-wide to avoid fixing violations
- Run
cargo nextest run --locked --workspace to verify fixes did not break behavior
Adding a disallowed method
Add to the disallowed-methods list in native/rust/clippy.toml:
disallowed-methods = [
{ path = "std::iter::Iterator::for_each", reason = "Use a `for` loop for side effects" },
{ path = "your::new::method", reason = "Explanation of why it is banned" },
]
Suppressing a Lint
Per-site (preferred)
#[allow(clippy::too_many_arguments)]
fn complex_jni_bridge(a: i32, b: i32, c: i32, ...) { ... }
Always add a comment explaining why the suppression is necessary.
Per-crate (rare, JNI only)
The workspace already allows missing_safety_doc and not_unsafe_ptr_arg_deref for JNI crates. Adding new per-crate allows requires justification in the commit message.
Never suppress workspace-wide
If a lint produces too many false positives across the entire workspace, reconsider whether it belongs in the config at all rather than setting it to "allow".
Common Mistakes
| Mistake | Fix |
|---|
| Adding lint config to a specific crate's Cargo.toml | All lints are workspace-level; crates use [lints] workspace = true |
| Suppressing lint workspace-wide to avoid fixing code | Fix the violations or add per-site #[allow] with TODO |
Running cargo clippy --locked without --all-targets | Tests and examples need linting too |
Forgetting -- -D warnings in CI | Warnings must be treated as errors in CI |
Adding a dependency without running cargo deny --locked check | New deps may violate license or advisory policy |
| Using unstable rustfmt options | rustfmt.toml uses only stable options (edition, max_width, use_small_heuristics) |
| Raising thresholds in clippy.toml to avoid refactoring | Fix the code; thresholds are already generous (8 args, 300 type complexity) |