Rust’s compiler is the most opinionated code reviewer most developers will ever work with. Its ownership system, borrow checker, and lifetime enforcement eliminate entire categories of bugs that plague C and C++ codebases. But a compiler that prevents memory errors is not the same as a comprehensive quality system. Logical bugs, insecure dependency chains, unsafe block misuse, performance anti-patterns, and style drift all survive rustc. Teams that ship reliable Rust at scale combine the compiler with a layered set of static analysis tools, each covering a different part of the quality surface.
Choosing the wrong combination wastes CI time and generates noise developers learn to ignore. Choosing the right one makes the compiler’s strictness feel like a floor rather than a ceiling. The tools in this guide are organized by what they actually do, not alphabetically, so teams can build a stack that covers all three quality layers: linting and idioms, dependency security, and deep verification for safety-critical or security-sensitive code
SMART TS XL
Die Aufrechterhaltung der Qualität in der modernen Rust-Entwicklung ist selbst mit den starken Sicherheitsgarantien der Sprache eine Herausforderung. SMART TS XL wurde entwickelt, um Teams bei der Entwicklung zuverlässiger, wartungsfreundlicher und sicherer Software zu unterstützen. Es bietet umfassende statische Analysefunktionen, die auf die einzigartigen Funktionen von Rust zugeschnitten sind. Es unterstützt professionelle Engineering-Workflows, indem es Probleme frühzeitig erkennt, Konsistenz sicherstellt und den manuellen Prüfaufwand reduziert.
The Three Layers of Rust Static Analysis
Understanding which tool belongs where prevents the common mistake of using a formal verifier where a linter would do, or relying on a linter where a security scanner is required. Every mature Rust project should cover all three layers.
Layer 1: Linting and style catches idiomatic violations, common mistakes, and maintainability problems. Tools: Clippy, rustfmt, rust-analyzer.
Layer 2: Dependency and supply chain security audits third-party crates for known vulnerabilities and policy violations. Tools: cargo-audit, cargo-deny, cargo-auditable.
Layer 3: Deep verification finds memory safety issues in unsafe code, undefined behavior, and formally proves properties of critical functions. Tools: Miri, Kani, MIRAI, Rudra, Creusot, Prusti.
The table below maps each major tool to its layer, cost, CI suitability, and primary use case:
| Werkzeug | Schicht | Kosten | CI Suitable | Primärer Anwendungsfall |
|---|---|---|---|---|
| Clippy | Flusen | Free / OSS | Ja | Idiomatic linting, style, common bugs |
| rustfmt | Flusen | Free / OSS | Ja | Code formatting enforcement |
| Rost-Analysator | Linting / DX | Free / OSS | Teilweise | IDE diagnostics, inline analysis |
| Fracht-Audit | Dependency security | Free / OSS | Ja | Known CVEs in crates |
| cargo-deny | Dependency security | Free / OSS | Ja | License, duplicates, advisories |
| cargo-auditable | Dependency security | Free / OSS | Ja | Embed dependency data in binaries |
| Miri | Tiefenprüfung | Free / OSS | Ausgewähltes Personal | Undefined behavior in unsafe code |
| Kani | Tiefenprüfung | Free / OSS | Ausgewähltes Personal | Formal verification, model checking |
| MIRAI | Tiefenprüfung | Free / OSS | Ausgewähltes Personal | Abstract interpretation, taint analysis |
| Rudra | Tiefenprüfung | Free / OSS | Forschung | Memory safety bugs in unsafe Rust |
| Semgrep | Querschnitt | Kostenloses Angebot + kostenpflichtiges Angebot | Ja | Custom security patterns, multi-language |
| SonarCloud | Querschnitt | Kostenloses Angebot + kostenpflichtiges Angebot | Ja | Continuous quality gate, dashboards |
Layer 1: Linting, Style, and Developer Experience
Clippy
Clippy is the definitive starting point for Rust static analysis. Shipped with the official Rust toolchain, it provides over 700 lints covering correctness, performance, style, complexity, and restrictions. It is the tool most Rust teams use daily, and for good reason: it catches real bugs, not just style opinions.
bash
# Run all lints including pedantic and nursery groups
cargo clippy -- -W clippy::all -W clippy::pedantic
# Fail CI on any warning
cargo clippy -- -D warnings
# Check specific lint group
cargo clippy -- -W clippy::correctness -W clippy::suspicious
Clippy’s lint categories are worth understanding explicitly:
| Kategorie | Was es fängt |
|---|---|
correctness | Code that is almost certainly wrong (always deny) |
suspicious | Code that is likely wrong or very surprising |
style | Non-idiomatic patterns with a clear improvement |
complexity | Unnecessarily complex constructs |
performance | Code that compiles but runs slower than it should |
pedantic | Strict guidelines, opinionated (enable selectively) |
restriction | Rules you may want to enforce in specific contexts |
nursery | New lints, may produce false positives |
cargo check vs clippy: cargo check validates type correctness and compilation without generating a binary. It is fast and appropriate for build verification. cargo clippy läuft cargo check plus all lint analysis. For CI, run cargo check for fast compilation feedback and cargo clippy -- -D warnings as a separate quality gate. They are not interchangeable: cargo check will not catch idiomatic problems, and cargo clippy ist langsamer.
Configuring Clippy clippy.toml or inline attributes gives teams control over noise:
Toml
# clippy.toml
avoid-breaking-exported-api = false
msrv = "1.70"
Rost
// Suppress a lint for one function with documented reason
#[allow(clippy::too_many_arguments)]
fn complex_setup(...) { ... }
What Clippy does not cover: deep data-flow analysis across modules, security vulnerability scanning in dependencies, formal proof of correctness, or custom organization-specific rules. These require tools in the other layers.
rustfmt
rustfmt enforces consistent formatting across the entire codebase using cargo fmt. Der rustfmt.toml configuration file sets project-wide style rules. In CI, cargo fmt -- --check exits with a non-zero code if any file would be reformatted, making it a clean quality gate with no configuration overhead:
bash
# Check formatting without modifying files (CI mode)
cargo fmt -- --check
# Apply formatting (developer mode)
cargo fmt
rust-analyzer and IDE Integration
rust-analyzer is the Language Server Protocol implementation for Rust, providing real-time diagnostics, completion, go-to-definition, and inline Clippy warnings in any LSP-compatible editor. It replaced the deprecated RLS (Rust Language Server) and should be the only language server used in new projects.
From a static analysis perspective, rust-analyzer surfaces Clippy lints inline as developers type, giving immediate feedback on style and correctness issues at the point of introduction rather than requiring a separate terminal run:
JSON
// VS Code settings.json: enable Clippy via rust-analyzer
{
"rust-analyzer.check.command": "clippy",
"rust-analyzer.check.extraArgs": [
"--", "-W", "clippy::all", "-W", "clippy::pedantic"
]
}
rust-analyzer also provides inlay hints for inferred types, borrow lifetimes, and parameter names, which are useful for reviewing unfamiliar code without navigating to definitions.
Layer 2: Dependency and Supply Chain Security
Fracht-Audit
cargo-audit checks the Cargo.lock file against the RustSec Advisory Database, identifying known CVEs in direct and transitive dependencies. It is the minimum dependency security tool every Rust project should run in CI.
bash
# Install
cargo install cargo-audit
# Run audit
cargo audit
# Ignore a specific advisory (document the reason in comments)
cargo audit --ignore RUSTSEC-2024-0001
# JSON output for pipeline integration
cargo audit --json | jq '.vulnerabilities'
cargo-audit covers known, published advisories only. It cannot detect vulnerabilities in your own code, issues not yet in the RustSec database, or policy violations like unwanted licenses.
cargo-deny
cargo-deny extends dependency management beyond known CVEs to license compliance, duplicate crate detection, and custom ban/allow policies. It is the more comprehensive tool for organizations with compliance requirements:
Toml
# deny.toml
[advisories]
vulnerability = "deny"
unmaintained = "warn"
[licenses]
allow = ["MIT", "Apache-2.0", "ISC", "BSD-2-Clause", "BSD-3-Clause"]
deny = ["GPL-2.0"]
copyleft = "warn"
[bans]
multiple-versions = "warn"
bash
cargo install cargo-deny
cargo deny check
cargo-auditable
cargo-auditable embeds the complete dependency tree into compiled Rust binaries as structured metadata in a dedicated linker section. This makes it possible to audit deployed binaries without access to source code, valuable for post-deployment security review and supply chain transparency:
bash
cargo install cargo-auditable
cargo auditable build --release
# The binary now contains auditable dependency metadata
# Audit a binary directly:
cargo audit bin ./target/release/my-service
Layer 3: Deep Verification
The tools in this layer require more setup, more expertise, and longer analysis times. They are not appropriate for every function in every codebase. They are essential for unsafe code, cryptographic implementations, parser logic handling untrusted input, and any code where correctness needs to be proved rather than tested.
Miri: Undefined Behavior Detection
Miri is an interpreter for Rust’s Mid-Level Intermediate Representation (MIR) that executes code in a way that detects undefined behavior the compiler allows but that violates Rust’s safety guarantees: out-of-bounds memory access in unsafe blocks, use-after-free, misaligned pointer dereferences, data races in multi-threaded unsafe code, and violations of Rust’s aliasing model.
bash
# Install Miri (requires nightly)
rustup +nightly component add miri
# Run tests under Miri
cargo +nightly miri test
# Enable strict aliasing validation
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test
What Miri detects: undefined behavior in unsafe blocks, memory access violations, use-after-free, misaligned accesses, integer overflow in debug builds, data races in unsafe concurrent code.
What Miri does not cover: logic bugs in safe code that do not involve undefined behavior, dependency vulnerabilities, code style, or performance issues.
CI-Integration: Miri runs 10-50x slower than cargo test. Run it selectively on modules containing unsafe code, or on a nightly schedule rather than on every commit:
YAML
- name: Miri on unsafe modules
run: |
rustup +nightly component add miri
cargo +nightly miri test --package my-unsafe-crate
Kani: Model Checking and Formal Verification
Kani, developed by Amazon Web Services, is a model checker that formally verifies properties of Rust code by exhaustively exploring execution paths up to a defined bound. Where Miri runs actual test cases and finds concrete bugs, Kani proves or disproves that properties hold for all inputs within its analysis scope.
Kani requires writing verification harnesses: functions that define the input space and the properties to verify:
Rost
#[cfg(kani)]
mod verification {
use super::*;
#[kani::proof]
fn verify_add_no_overflow() {
let a: u32 = kani::any();
let b: u32 = kani::any();
if a.checked_add(b).is_some() {
let result = safe_add(a, b);
assert!(result == a + b);
}
}
}
bash
cargo install --locked kani-verifier
cargo kani setup
cargo kani
Best suited for: safety-critical functions, protocol implementations, arithmetic in financial or cryptographic code, and any function where you need to prove, not just test, a correctness property.
MIRAI: Abstract Interpretation and Taint Analysis
MIRAI, developed by Facebook Research, uses abstract interpretation to analyze Rust’s MIR. It performs interprocedural analysis that tracks how values flow through function calls, detecting potential panics, contract violations, and taint propagation through code.
Rost
use mirai_annotations::*;
fn divide(a: i32, b: i32) -> i32 {
precondition!(b != 0); // MIRAI verifies all callers satisfy this
a / b
}
MIRAI requires a nightly Rust compiler and has a steep setup curve, making it most appropriate for teams with dedicated security engineering capacity or research-oriented quality requirements.
Rudra: Memory Safety in Unsafe Library Code
Rudra performs whole-program analysis across crates to detect memory safety bugs specific to Rust’s ownership model: Send/Sync trait safety violations, higher-kinded lifetime issues that allow unsound lifetime extension, and panic safety issues in unsafe code. Originally developed by researchers, it operates as a compiler plugin and requires a specific nightly version. Run it on a scheduled basis for library crates with unsafe internals rather than on every commit.
Creusot and Prusti: Deductive Verification
Creusot and Prusti are deductive verification tools that prove mathematical properties of Rust programs. Both require formal specifications (preconditions, postconditions, loop invariants) and use automated theorem provers to verify implementations against those specifications. They target a restricted subset of safe Rust and require formal methods expertise. Appropriate for regulated industries, cryptographic library development, or any context where mathematical proof of correctness is a contractual or regulatory requirement.
Additional Tools Worth Including
Semgrep for Custom Security Patterns
Semgrep provides pattern-based static analysis that works across multiple languages simultaneously. For Rust, it enables teams to write custom rules enforcing organizational security policies and codebase-specific patterns that Clippy cannot express:
YAML
# Custom rule: flag .unwrap() in production paths
rules:
- id: no-unwrap-in-production
pattern: $X.unwrap()
message: "Use proper error handling instead of .unwrap()"
languages: [rust]
severity: WARNING
Semgrep also provides a managed rule registry with Rust security rules maintained by the community.
SonarCloud / SonarQube for Continuous Quality Gates
SonarCloud provides continuous code quality analysis with a dashboard, trend tracking, and pull request decoration. Its Rust support covers common bug patterns, security hotspots, and code smells. For enterprise teams already using SonarCloud for other languages, adding Rust to the same pipeline provides unified quality visibility across the stack.
Building a Layered CI/CD Pipeline
The following GitHub Actions workflow represents a practical starting point for teams who want comprehensive Rust quality coverage without over-engineering:
YAML
# .github/workflows/quality.yml
name: Code Quality and Security
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Check formatting
run: cargo fmt -- --check
- name: Clippy (treat warnings as errors)
run: cargo clippy -- -D warnings
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install security tools
run: |
cargo install cargo-audit
cargo install cargo-deny
- name: Dependency audit
run: cargo audit --deny warnings
- name: License and policy check
run: cargo deny check
verify:
runs-on: ubuntu-latest
# Scheduled or manually triggered, not on every push
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: miri
- name: Miri on unsafe modules
run: cargo +nightly miri test --package my-unsafe-crate
Which Tool Should You Use? Decision Guide
Starting a new Rust project: Clippy + rustfmt + cargo-audit. Configurable in under five minutes, catches the majority of quality and security issues teams encounter.
Production service with external dependencies: Add cargo-deny for license compliance and supply chain policy enforcement beyond CVEs.
Library crate with unsafe internals: Add Miri to your test suite for modules containing unsafe code. Run Rudra on a scheduled basis.
Safety-critical or cryptographic code: Write Kani verification harnesses for the most critical functions. Consider Creusot or Prusti if the team has formal methods expertise.
Security-focused organization: Add Semgrep with custom rules for organizational security policies, plus cargo-auditable in release builds.
Continuous visibility for a larger team: SonarCloud for trend tracking, pull request decoration, and quality gates alongside the open-source tools.
Polyglot enterprise environment where Rust interacts with COBOL, Java, or other legacy languages: single-language Rust tools cannot see across the language boundary. SMART TS XL provides the cross-language analysis that covers the full system.
When Rust Static Analysis Meets Enterprise Systems
Rust is increasingly used for new services in organizations that also run COBOL, Java, PL/I, or RPG on mainframe or legacy platforms. In these environments, the static analysis picture extends beyond what any Rust-specific tool can see. A Rust microservice may call a COBOL program, write to a shared database, or consume events produced by a legacy batch system. The quality and dependency analysis that matters to an enterprise architect spans all of those systems simultaneously.
SMART TS XL addresses this gap by providing cross-language dependency analysis across the full application portfolio. Where Clippy and cargo-audit see only Rust, SMART TS XL maps how a Rust service depends on shared data structures, legacy programs, and enterprise APIs, and what the impact of changing any of those dependencies would be. This makes it the tool of choice for Wirkungsanalyse als auch Planung der Modernisierung bestehender Systeme in environments where Rust is one language among many.
For teams adopting Rust incrementally within a larger enterprise codebase, SMART TS XL statische Code-Analyse provides the structural visibility needed to understand how Rust components fit into the larger system before making changes that might affect components written in other languages. As examined in the context of Abhängigkeitsgraphen und Anwendungsrisiko, mapping the full dependency structure before extending a system is what separates changes that go smoothly from those that produce failures in components nobody thought to test.
The Layered Approach Is the Point
Static analysis in Rust is not a single tool decision. It is a layered discipline that starts with what the compiler gives you for free and extends outward based on the risk profile of your code. Clippy and rustfmt are the floor. cargo-audit is non-negotiable for any project with external dependencies. Miri belongs in any project with unsafe code. Kani and the formal verification tools are for the functions where getting it wrong is unacceptable.
The teams that get this right integrate static analysis into the development loop: Clippy inline in the editor, cargo-audit in every CI run, and Miri in a nightly job that catches what tests alone cannot. The result is not just fewer bugs. It is the kind of confidence in the codebase that lets teams make changes quickly, knowing that the analysis layers between a developer and production are working correctly.