Skip to content

fix(scanner): Resolve Rust use trees - #124

Draft
reneleonhardt wants to merge 1 commit into
JordanCoin:mainfrom
reneleonhardt:fix/rust-use-trees
Draft

fix(scanner): Resolve Rust use trees#124
reneleonhardt wants to merge 1 commit into
JordanCoin:mainfrom
reneleonhardt:fix/rust-use-trees

Conversation

@reneleonhardt

Copy link
Copy Markdown
Contributor

What does this PR do?

Resolve local crate, self, and super use trees, including nested groups, aliases, self, and glob module imports. External imports retain the existing scanner path, while malformed and generated routes remain conservative.

Type of change

  • Bug fix
  • New feature
  • New language support
  • Documentation
  • Other (describe below)

Checklist

  • I've tested this locally with go build && ./codemap .
  • I've read CONTRIBUTING.md; this does not add a new language.
  • Documentation is unchanged because this corrects existing Rust scanning.

Additional notes

Focused parser/extraction/resolution tests, go vet ./..., and the full race/coverage suite are GREEN.

On GitButler's 978-file Rust corpus, the change adds 588 specific local-module edges and removes 75 false crate/test-root fallback edges. Existing external imports and leading hub counts are preserved.

This branch targets until that prerequisite lands.

Developed with carefully directed, manually reviewed AI assistance.

Resolve grouped Rust use trees (use crate::{a, b}) into per-path dependency
references, including aliased imports.

Co-Authored-By: GPT-5.6 Sol <codex@openai.com>
@JordanCoin

Copy link
Copy Markdown
Owner

Reviewed and approved on the merits — but #126 just landed and this is now DIRTY, so it needs a rebase before I can merge it. That was unavoidable: all four Rust PRs edit the same m.RuleID disjunction in scanner/astgrep.go and the same two switches, so whichever lands first makes the other three conflict. Not a criticism of how they were split; just the shape of the collision.

What I verified, by dumping the full resolved edge set from BuildFileGraph on both main and this branch against a real 2-crate workspace (cargo check --workspace clean first):

main:  caller.rs -> [caller/helper.rs, exports.rs, lib.rs]        <- lib.rs is a false crate-root fallback
PR:    caller.rs -> [alpha.rs, beta.rs, caller/helper.rs,
                     exports.rs, nested/leaf.rs, nested/mod.rs]   <- all correct

Net on the fixture: +6 true edges, −2 false edges, 0 new false edges. std::collections::{BTreeMap, HashMap} correctly yields nothing, and use crate::* yields nothing rather than a wrong target. The expansion is a pure syntactic prefix-join, so it can't invent a path that isn't a genuine prefix of the source tree — that's the right property.

One thing worth folding in while you rebase (~3 lines): the claim that malformed trees "remain conservative" isn't quite true today. The gate at astgrep.go:351 only upgrades kind on success; on failure the reference falls through as rust-path carrying raw brace text, which resolveRustPath splits on :: into garbage and then hits rootFallback, emitting an edge to the crate root. Both of these are valid Rust and both produce a false edge:

use crate::{/* note */ alpha::Thing, beta};   // -> lib.rs   (should be alpha.rs + beta.rs)
use crate::{};                                 // -> lib.rs   (a no-op import inventing an edge)

Setting a kind that resolves to nothing when expansion fails on a brace-bearing path would make the PR's own claim true and delete two false edges.

Not blocking, for later: use crate::* now yields no edge where main produced one (under-reporting, so it doesn't violate the contract, but a correct edge is lost); and grouped pub use never reaches the new code at all, because the sg-rule patterns don't match a use_declaration with a visibility modifier — re-export hubs stay invisible. Neither is claimed in the PR body, just flagging so they're not assumed fixed.

Suggested order for the remaining three: this one next (only the rebase), then #127 (needs the println! rule scoped — it currently matches every println! in every Rust file), then #125 (needs the files[0] != target guard, or #130 fixed first, which makes it moot). Also: the resolver for the astgrep.go conflict must union all three rule IDs — taking either side silently disables a feature with fully green CI.

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.

2 participants