Call graph: index inline-module candidates instead of scanning every Rust file per reference
Speeds up building a call graph from scratch for large Rust projects. Stored results are identical.
Cause. During reference resolution, every qualified Rust call looked for inline modules (mod name { ... }) that might hold its target by scanning every Rust file in the project, once per reference, on the single resolver thread. On AFT's own checkout that one lookup was about 77% of cold-build CPU.
Fix. Each resolution snapshot builds one index of inline-module candidates by source and module prefix, and lookups visit only files that can match. Caller-first lookup, global path order among eligible candidates, scoped-symbol lookup and inline-before-module-file precedence are unchanged. It serves cold builds (including inspect-triggered cold repair), lazy refreshes reached from inspect and dead-code maintenance, and eager view joins. There is no result memoization, no resolver parallelism and no change to cold-build slots.
Measured on one unswapped Linux 12-vCPU pair, the same pinned corpus for both arms (5,513 files):
| before | after | |
|---|---|---|
| cold call graph ready | 635.8 s | 154.1 s |
| process CPU | 595 s | 177 s (−70%) |
| reference resolution | 489.9 s | 84.9 s |
| peak RSS | 836 MiB | 768 MiB |
Reference resolution alone is about 5.8 times faster. The whole-build ratio is confounded by host load during the baseline arm.
Parity. All 1,041,400 stored refs (21 columns) and 223,362 edges (9 columns) match row for row, so the build-output version is unchanged and nobody rebuilds. A candidate-count regression runs the original scan and the indexed lookup side by side, for eager and lazy project indexes, and checks precedence.
Verified after merging current main: 610 call-graph and inspect library tests, formatting and the Windows compile check. One existing scheduler-contention health test (disabled_callgraph_store_reports_disabled_despite_lingering_build_receiver) failed its retry-count assertion in that run, as it has before only under parallel load on the build server. It doesn't touch this change.
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Speeds up cold call-graph builds for large Rust projects by indexing inline-module candidates once per resolution snapshot instead of scanning every Rust file for each qualified reference. Stored results are unchanged, so no rebuild is needed.
Reference resolution drops from ~490s to ~85s (~5.8x faster) on a pinned 5,513-file corpus, with process CPU down about 70%. Caller-first lookup, global path order among candidates, scoped-symbol lookup, and inline-module-before-module-file precedence are preserved. The index covers cold builds, inspect-triggered cold repair, lazy refreshes, dead-code maintenance, and eager view joins; there is no result memoization or resolver parallelism.