Skip to content

Improve Rust callgraph resolution for direct self fields - #196

Open
onedotmint wants to merge 5 commits into
cortexkit:mainfrom
onedotmint:fix/rust-self-field-callgraph-resolution
Open

Improve Rust callgraph resolution for direct self fields#196
onedotmint wants to merge 5 commits into
cortexkit:mainfrom
onedotmint:fix/rust-self-field-callgraph-resolution

Conversation

@onedotmint

@onedotmint onedotmint commented Aug 8, 2026

Copy link
Copy Markdown

Summary

While testing Rust callgraph output, I ran into a case where Holder::check calls PathBuf::as_path, but AFT could still produce an approximate edge to an unrelated PrinterPath::as_path elsewhere in the project. So i create this pr and explain what I do.

The existing name_match fallback is useful when the receiver type is genuinely unknown, so I didn't want to remove or weaken that behavior. The issue here is that for a simple field receiver like self.path, we can sometimes recover enough local type information to make a better decision — and when we can't, guessing by method name can be misleading.

What changed

This adds a conservative path for direct self.field.method() calls.

When the field can be tied to a concrete local type in the same lexical scope, AFT uses the existing precise type_match path. For example, if self.engine is known to be an Engine, Car::run -> Engine::start is resolved precisely.

If the field is clearly present but its type can't be resolved safely, the call is left unresolved instead of being connected to an unrelated same-named method. Precise candidates are also checked against the field type's lexical module scope, so a same-named type inside a nested module can't accidentally become the target.

I intentionally kept this narrow. This isn't meant to add general Rust type or module resolution. Imported or scoped types, nested fields, generics, trait impls, references, aliases, wrappers, deref/coercion, and cross-file type identities stay conservative unless AFT already knows how to resolve them.

Tests

The tests cover the original PathBuf / PrinterPath case, precise resolution for a local field type, preservation of the existing name_match fallback for genuinely unknown receivers, and the scoped/imported/nested-module cases that could otherwise create false precise edges.

The relevant unit and integration tests pass, along with:

cargo check -p agent-file-tools
cargo fmt --check
git diff --check

The full crate suite still has four failures in this local environment. I reproduced all four against a clean worktree at the same HEAD with the same failure signatures, so they appear to be baseline/environment-related rather than introduced by this change.(I guess it's because of my base environment.)

Thanks for your project. It helps a lot in my coding time.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Improves Rust callgraph accuracy for direct self.field.method() calls, including spaced forms like self .engine.start(). Resolves only when the field’s type is a proven local concrete struct in the same file and module, and suppresses name-only matches when the field is known but unsafe to resolve.

  • Bug Fixes
    • Add conservative Rust self-field inference that uses type_match only when the field’s type is a concrete, local, non-generic struct in the same file and lexical module; validates inherent impl by checking the candidate’s start_line, file, and module scope; rejects trait and generic impls.
    • Normalize whitespace by storing a trimmed receiver_expression, so forms like self .engine and self. engine are detected.
    • When a self field exists but its type can’t be safely proven (nested fields, wrappers, references, aliases, generics, trait impls, imports, cross-file types, or nested same-named types), leave the call unresolved and skip name_match; genuinely unknown receivers keep the fallback.

Written for commit 952522a. Summary will update on new commits.

Review in cubic

Greptile Summary

The PR improves Rust callgraph resolution for direct self.field.method() calls while preserving conservative behavior when the field type cannot be proven.

  • Retains the full receiver expression and normalizes whitespace around direct field access.
  • Resolves locally declared concrete field types through scoped inherent implementations.
  • Suppresses misleading name-only fallback when a direct self field is recognized but unresolved.
  • Adds unit and integration coverage for precise, unresolved, scoped, and whitespace-separated cases.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
crates/aft/src/callgraph_store/mod.rs Adds conservative Rust direct-self-field inference, lexical-scope validation, and whitespace normalization; the previously reported whitespace bypasses are resolved.
crates/aft/tests/integration/callgraph_store_name_match_test.rs Adds end-to-end coverage for precise field-type resolution and suppression of unrelated method-name matches, including whitespace after the field-access dot.

Reviews (5): Last reviewed commit: "Clarify unresolved Rust field test names" | Re-trigger Greptile

Comment thread crates/aft/src/callgraph_store/mod.rs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/aft/tests/integration/callgraph_store_name_match_test.rs Outdated
Comment thread crates/aft/src/callgraph_store/mod.rs
Comment thread crates/aft/src/callgraph_store/mod.rs Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread crates/aft/tests/integration/callgraph_store_name_match_test.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant