Languages / Rust

Rust code analysis: unused code, call graphs and complexity

Rust's compiler already warns about unused private items through the dead_code lint, and cargo-udeps or cargo-machete find unused crates. repowise covers what those leave: public items and files no other crate in the Cargo workspace reaches, Axum and Actix routes as entry points, and performance markers for sqlx and reqwest calls inside loops.

Last reviewed: November 2026

Full tier

What repowise detects in Rust

Checked against the engine source. Every row runs locally with zero LLM calls.

repowise capabilities for Rust
Files parsed.rs
Import resolutionFull. crate::, self:: and super:: paths, mod declarations, #[path] attributes, src/bin crate roots, one-hop pub use re-exports, Cargo workspace members
Call graphResolved calls with a confidence per edge, plus heritage
Dead codeUnreachable files and unused public items across the Cargo workspace
Health markersComplexity, class metrics, Extract Method plans
Performance markerssqlx, std::fs and reqwest calls in loops, Regex::new in loops, client and pool construction in loops, block_on or std::thread::sleep inside async fn
Coverage reportslcov from cargo-llvm-cov, Cobertura
Frameworks recognisedAxum .route, Actix web::get().to

Specific to this language

How Rust code is read

Cross-module exports, beside rustc

rustc's dead_code lint covers private items; repowise covers cross-module exports: a pub item no other crate in the workspace uses, and module files nothing reaches.

Markers that keep code alive

Items with #[no_mangle], extern "C", proc-macro attributes, #[doc(hidden)], #[allow(dead_code)] or #[deprecated] are exempt. Box<dyn ...>, inventory::submit!, serde derives and #[cfg(feature ...)] lower confidence nearby. examples/, benches/, tests/, src/bin/ and fuzz targets are entry points.

Async and I/O risk

Blocking calls inside async fn (block_on, std::thread::sleep, synchronous std::fs) are flagged, as are sqlx queries and reqwest calls inside for loops and a new reqwest::Client or PgPool per iteration. String push_str in loops is deliberately not flagged: it is amortised O(1).

Honest comparison

Native Rust tools, and when they are enough

Native Rust analysis tools
ToolWhat it covers
rustc dead_code lintUnused private functions, types and fields, exact, on every build.
ClippyHundreds of lints, including complexity and performance lints.
cargo-udeps, cargo-macheteUnused crate dependencies in Cargo.toml.
cargo-llvm-covCoverage; writes lcov, which repowise reads.
cargo-modulesModule structure and dependency graphs for one crate.

Where repowise adds value

  • Unused public items and files across a Cargo workspace, which the per-crate lint does not report.
  • Hotspots, ownership and co-change from git history, with a health score per file.
  • A graph that includes the TypeScript, Python or Go code in the same repository.

How to run it

Analyse a Rust repository

From the repository root. Agents get the same results through the get_dead_code, get_health and get_context MCP tools.

uv tool install repowise        # or: pipx install repowise
repowise init --yes --no-prose     # index the repo, no API key
repowise dead-code --min-confidence 0.7 --safe-only
repowise health --refactoring-targets
cargo llvm-cov --lcov --output-path lcov.info
repowise coverage add lcov.info
repowise serve                     # graph, health and dead code in a local dashboard

Questions

What people ask before they try it.

How does repowise work with rustc's dead_code lint?

rustc's dead_code lint covers private items on every build; repowise covers cross-module exports: public items unused across the workspace and module files nothing reaches.

Does it understand Cargo workspaces?

Yes. It reads [workspace] members, maps crate names (foo-thing becomes foo_thing) and resolves crate::, self::, super:: and mod paths across member crates.

Which Rust web frameworks are recognised?

Axum .route registrations and Actix web::get().to handlers become edges. Other frameworks fall back to ordinary call and import resolution.

Does repowise send my Rust code to an LLM?

No. Parsing, the call graph, dead code, health scores, performance markers and git history all run locally with zero LLM calls. repowise init --yes --no-prose needs no API key, and the analysis itself makes no network calls. Written documentation prose is the one opt-in step that uses a model, and it can run on a local Ollama model.

Index a Rust repository.

Public repositories are free on repowise.dev. The CLI is open source and runs on your machine with no API key.