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 andtraits (with supertraits). - The methods of
implblocks go to their type; trait implementations are listed underimplements. - Functions with visibility (
pub,pub(crate)…),async, parameters and return type;macro_rules!macros. - Fields,
const/staticitems, type aliases and enum variants. - Flattened
usetrees, path / method / macro calls,if/matchbranches, 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.
| Category | When |
|---|---|
internal_helper | the file's own types, functions and methods (self.x(), Self::x()) |
module_use | another module of the crate (crate::, super::), shown as module::fn / Type::fn |
native_rust | std / core / alloc, the prelude and common std methods |
framework_use | known framework crates (axum, tower, hyper, actix_web, rocket, tokio, serde, clap, diesel, sqlx, bevy…) |
package_use | another crate (an external dependency) |
macro_use | every macro call; the macro is not expanded |
external_call | a 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. cfgattributes 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 yoursrcfolder.