callgraph

Rust call graph and impact analysis for AI agents

callgraph parses .rs files with syn and gives your agent modules, structs, traits and impl blocks with exact line ranges, every call sorted by category, and who calls a function across the crate — without reading the file.

What callgraph extracts from Rust

  • The file module, inline mods, structs, enums, unions and traits (with supertraits).
  • The methods of impl blocks go to their type; trait implementations are listed under implements.
  • Functions with visibility (pub, pub(crate)…), async, parameters and return type; macro_rules! macros.
  • Fields, const / static items, type aliases and enum variants.
  • Flattened use trees, path / method / macro calls, if / match branches, string literals (also in attributes such as #[get("/users/{id}")]).

Framework awareness: axum, actix-web, tokio…

The framework comes from the nearest Cargo.toml above the file: the first known dependency, in this order — bevy, tauri, leptos, dioxus, yew, axum, actix-web, rocket, warp, poem, diesel, sqlx, sea-orm, clap, tokio, async-std, serde. Calls into known framework crates are labelled framework_use, and profile recognises a Rust web architecture.

CategoryWhen
internal_helperthe file's own types, functions and methods (self.x(), Self::x())
module_useanother module of the crate (crate::, super::), shown as module::fn / Type::fn
native_ruststd / core / alloc, the prelude and common std methods
framework_useknown framework crates (axum, tower, hyper, actix_web, rocket, tokio, serde, clap, diesel, sqlx, bevy…)
package_useanother crate (an external dependency)
macro_useevery macro call; the macro is not expanded
external_calla local variable or closure, or a method on an unknown receiver (?::name)

Commands

CG=~/.claude/skills/callgraph/callgraph.sh
bash $CG --project myapp src/api/users.rs              # outline: struct/impl/trait, fns with line ranges
bash $CG --project myapp src/api/users.rs --format api # pub items, incl. the pub fn of impl blocks
bash $CG --project myapp src --const MAX_ITEMS         # const / static (also Type::CONST): definition + uses

--const also shows where a name is passed on, for example pub use state::{CheckState, STATE_FILE}; appears as [re-export] state::STATE_FILE.

Who calls this Rust function?

bash $CG --project myapp src --grep 'Repo::find'                # crate-internal: Type::fn / module::fn
bash $CG --project myapp src --grep '(^|::|\.|->)find$'         # every call of the name
bash $CG --project myapp src --grep 'Repo::find' --depth 3      # callers of callers

For a method called on a value (x.load()) callgraph works out the type of x in the simple, reliable cases: a parameter type (x: &Repo, Box / Rc / Arc, an extractor like State(s): State<App>), let x = Repo::new(), a struct literal, self, or a field of your own struct (self.repo.load()). Then the call shows up as Repo::load. When the type can't be worked out, it is kept as ?::load, and a Repo::load search still lists it, marked as uncertain — instead of silently missing it.

Limits

  • Macros are not expanded: code generated by derive, attribute or function-like macros is not visible.
  • Type inference is deliberately simple: return types and chained calls (a.b().c()) get no type.
  • cfg attributes are not evaluated: every branch, such as #[cfg(test)] mod tests, is included.
  • A file with a syntax error yields only the file container and a warning.
  • The walker does not skip target/; point callgraph at your src folder.