Skip to content

fix(rust): a module path names the module's free function, not a method - #2259

Closed
danusha2345 wants to merge 1 commit into
colbymchenry:mainfrom
danusha2345:fix/rust-crate-path-free-function
Closed

danusha2345 wants to merge 1 commit into
colbymchenry:mainfrom
danusha2345:fix/rust-crate-path-free-function

Conversation

@danusha2345

Copy link
Copy Markdown
Contributor

Problem

A Rust call written through a module path — crate::util::take(3), super::util::take(3), self::util::take(3), or util::take(3) after use crate::util; — maps the module prefix to its file correctly, then takes the first node of that name in the file. method was one of the accepted kinds, and a function local to another function's body was not ruled out. So a module that declares impl Buf { pub fn take(&self, …) } (or trait Take { fn take(&self); }) above its free pub fn take(…) sent every path call to the method; a module with only the method bound the call to it. use crate::util::take; landed on the method too and was then dropped, leaving no import edge.

Fix

In resolveRustPathReference, a Rust path never names a method (that is Type::method) nor a function-local item: drop method from the accepted kinds and keep only lexically reachable items (isLexicallyReachable, the same check #2224 applies to the framework heuristics). A module whose file declares no such item still falls through to name matching, which links nothing.

Tests

__tests__/rust-module-path-call.test.ts (real temp Cargo project + SQLite): crate/super/self/module-after-use paths, a use of the function, a nested a::b path, a module with only a same-named method, and a module not in the index. All 4 cases fail on main and pass with the fix (kernel and wasm extraction). Full suite on Linux passes.

A/B (calls edges, main → fix)

  • A GNSS simulator crate: 13 calls retargeted from GnssTimeConverter::utc_to_gps_time (and 6 siblings) to the module's free wrapper functions of the same name, plus 7 use crate::gnsstime::{…} import edges; every call site is a crate::gnsstime::<fn>(…) path, so 13/13 and 7/7 are correct.
  • Five other Rust crates: no change. Node counts unchanged everywhere.

Not in this PR

use crate::util::take; take(3) with another free take elsewhere (e.g. other.rs) still goes to the other one: the uses.bound set from #2214 keeps leaf names only, not the module the use names. Happy to follow up separately.

🤖 Generated with Claude Code

A call written through a module path (`crate::util::take(3)`,
`super::util::take(3)`, `self::util::take(3)`, `util::take(3)` after
`use crate::util;`) maps the module prefix to its file and then took the
first node of that name in it - `method` was among the accepted kinds, and
nothing ruled out a fn local to another fn's body. So an
`impl Buf { pub fn take }` above `pub fn take` caught every path call, and a
module with only the method bound the call to it. A Rust path never names a
method (that takes `Type::method`) nor a function-local item: drop `method`
from the kinds and keep only lexically reachable items (the same check
colbymchenry#2224 applies to the framework heuristics). A module whose file declares no
such item still falls through, and links nothing.

Side effect: `use crate::util::take;` of such a function now binds to it;
it used to land on the method and be dropped, leaving no import edge.

A/B on the user's Rust projects (copies, calls edges main -> fix):
gnss_rust 13 calls retargeted from `GnssTimeConverter::utc_to_gps_time`
(and 6 siblings) to the module's free wrappers of the same name, +7
`use crate::gnsstime::{...}` import edges; every call site is a
`crate::gnsstime::<fn>(...)` path - 13/13, 7/7 correct. usb-doctor,
emmc-reader-gui, skylab_gui, rp2350-dongle-emu, ld2416: no change.
Node counts unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Oct 1, 2026
…bymchenry#2259, colbymchenry#2260) into fork main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Oct 3, 2026
A bare call bound by a `use` (`use crate::util::take; take(3)`, also
through `as` aliases, nested groups, `self`/`super`/`crate` paths and
block-local imports) now resolves to the item that path names before
name matching runs. A parameter, `let` or nested fn of that name still
shadows the import. A binding the resolver cannot follow (another
workspace crate, a `pub use` re-export, a relative path inside an
inline module) keeps the previous resolution.

A module path (`crate::util::take(3)`) names the module's own item:
never a method, an associated item of an impl or trait body, or a
fn-local item. A module-level item wins over an inline module's item
reached through a re-export. Includes and supersedes colbymchenry#2259.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@danusha2345

Copy link
Copy Markdown
Contributor Author

Folded into #2308, which carries this PR's source change and its whole test file (plus an associated-type decoy case) and adds exact resolution of bare calls through their use binding on top. Closing this one so the two don't overlap.

@danusha2345 danusha2345 closed this Oct 3, 2026
danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Oct 6, 2026
A bare call bound by a `use` (`use crate::util::take; take(3)`, also
through `as` aliases, nested groups, `self`/`super`/`crate` paths and
block-local imports) now resolves to the item that path names before
name matching runs. A parameter, `let` or nested fn of that name still
shadows the import. A binding the resolver cannot follow (another
workspace crate, a `pub use` re-export, a relative path inside an
inline module) keeps the previous resolution.

A module path (`crate::util::take(3)`) names the module's own item:
never a method, an associated item of an impl or trait body, or a
fn-local item. A module-level item wins over an inline module's item
reached through a re-export. Includes and supersedes colbymchenry#2259.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Oct 7, 2026
A bare call bound by a `use` (`use crate::util::take; take(3)`, also
through `as` aliases, nested groups, `self`/`super`/`crate` paths and
block-local imports) now resolves to the item that path names before
name matching runs. A parameter, `let` or nested fn of that name still
shadows the import. A binding the resolver cannot follow (another
workspace crate, a `pub use` re-export, a relative path inside an
inline module) keeps the previous resolution.

A module path (`crate::util::take(3)`) names the module's own item:
never a method, an associated item of an impl or trait body, or a
fn-local item. A module-level item wins over an inline module's item
reached through a re-export. Includes and supersedes colbymchenry#2259.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Oct 7, 2026
A bare call bound by a `use` (`use crate::util::take; take(3)`, also
through `as` aliases, nested groups, `self`/`super`/`crate` paths and
block-local imports) now resolves to the item that path names before
name matching runs. A parameter, `let` or nested fn of that name still
shadows the import. A binding the resolver cannot follow (another
workspace crate, a `pub use` re-export, a relative path inside an
inline module) keeps the previous resolution.

A module path (`crate::util::take(3)`) names the module's own item:
never a method, an associated item of an impl or trait body, or a
fn-local item. A module-level item wins over an inline module's item
reached through a re-export. Includes and supersedes colbymchenry#2259.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Oct 10, 2026
A bare call bound by a `use` (`use crate::util::take; take(3)`, also
through `as` aliases, nested groups, `self`/`super`/`crate` paths and
block-local imports) now resolves to the item that path names before
name matching runs. A parameter, `let` or nested fn of that name still
shadows the import. A binding the resolver cannot follow (another
workspace crate, a `pub use` re-export, a relative path inside an
inline module) keeps the previous resolution.

A module path (`crate::util::take(3)`) names the module's own item:
never a method, an associated item of an impl or trait body, or a
fn-local item. A module-level item wins over an inline module's item
reached through a re-export. Includes and supersedes colbymchenry#2259.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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