Repository navigation
fix(rust): calls through a type a path or a use names reach that type's own function - #3025
Merged
Merged
Conversation
colbymchenry
force-pushed
the
claude/rust-cross-crate-paths
branch
10 times, most recently
from
October 30, 2026 06:32
180c9bd to
6655ff5
Compare
…'s own function A Rust call through a type, `sim::items::ItemPool::for_def(…)` into another crate of the workspace or `ItemPool::for_def(…)` under `use sim::items::ItemPool;`, was matched by its qualified name alone, so a namesake type's function in another crate or module could take it (a workspace's `client` crate's `ItemPool::for_def`). The module walk stopped at the type, a `use` of a `pub const` or `static` (`use sim::RANK_COUNT;`) linked nothing, and a type rustfmt wrapped below its path (`h: &scheduler::\n Handle`) linked by the file's `use` of its last name. The fix, on the module walk: - rustPathTarget reads `Type::member` calls: the type is the item the path's modules name, or the one the `use` that binds its name names (rustUseItemsAt), and rustTypeMember finds its member: an enum's variant; else the type's own (inherent) function or `const` in the type's crate, a trait impl's only when it is the one of that name; a trait's own declared method. A type alias, `Self`, a type the module declares itself and a type path in any other position are left as they were. - Module items include `variable`s (a module-level `pub const`/`static`). - matchRustUseBoundName reads a qualifier written on the line above a type (rust-scopes' blanked code, so a commented-out path is none) and resolves the whole path. - Memoized per (type, member) and per path. - Manifest paths stay inside the project: a workspace member that leaves it (`../sibling`, an absolute path) is neither read nor listed (escapesRoot, in expandMembers), and rustCrateGraph drops a `[lib]`/`[[bin]]` path that leaves it, as it already did a dependency's. Validation: - rust-cross-crate.test.ts (PR 2631's 9 cases, credited), rust-type-member-paths.test.ts and rust-manifest-paths.test.ts: on main 10 of 15 fail; all pass. Every rust-* suite passes. On main the workspace map read `../outside/Cargo.toml`, `../vendor/x/Cargo.toml` and `/abs/crate/Cargo.toml` and listed `../vendor`; now only the project's. - A/B against main, native kernel, 7 Rust repos (every site the same as against PR #3014's own commit; re-checked on 60b0d7a): tokio +205 links / 139 retargeted / 230 chains gaining their head call, ripgrep +155 / 13 / 1, axum +25, clap +179 / 0 / 295, serde +28, dioxus +142 / 6 / 31, gleam +114 / 47 / 0; 0 removed. Retargets go to the type the code imports or its own crate's (tokio's Semaphore::new and loom mocks to tokio::sync, ripgrep's Error::from, gleam's Printer::new); express and flask byte-identical. - Cost, native kernel, medians of 3 interleaved runs (dioxus of 7): tokio CPU 32.1 -> 29.7 s, peak RSS 1,000 -> 1,010 MB; gleam 29.1 -> 28.1 s, 1,010 -> 1,004 MB; dioxus 38.7 -> 40.1 s, 1,111 -> 1,115 MB (timed on one thread, rustPathTarget 1.24 -> 1.32 s over 17,198 calls). Builds on PR #2631 by @BGamboa13. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
colbymchenry
force-pushed
the
claude/rust-cross-crate-paths
branch
from
October 30, 2026 08:42
6655ff5 to
62b1491
Compare
This was referenced Oct 30, 2026
inth3shadows
added a commit
to inth3shadows/codegraph
that referenced
this pull request
Oct 30, 2026
Brings 9f379af..bc9291a (colbymchenry#3030, colbymchenry#3031, colbymchenry#3043, colbymchenry#3045, colbymchenry#3046, colbymchenry#3049, colbymchenry#3044, colbymchenry#3047, colbymchenry#3051, colbymchenry#3050, colbymchenry#3052, colbymchenry#3053, colbymchenry#3025, colbymchenry#3055). Clean auto-merge.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Builds on #2631 by @BGamboa13, on top of #3014's module walk: a Rust call through a type that a path or a
usenames now reaches that type's own function or variant, across the crates of a Cargo workspace too.sim::items::ItemPool::for_def(…)into another workspace crate,core_sim::items::…through a renamed path dependency,vendored::helper(…)through one outside the members.ItemPool::for_def(…)/Rng::new(…)underuse sim::items::ItemPool;/use sim::Rng;(a re-export),Handle::current()underuse crate::runtime::Handle;.crate::models::Mode::Fast(1): a variant through a module path;Codec::encode(&x): a trait's own method.use sim::RANK_COUNT;/use crate::ledger::{KEY_RANK_COUNT, LIMIT};: module-levelpub const/staticitems.h: &scheduler::\n Handle: a type rustfmt wrapped below its path links by that path, not by auseof its last name.../shared, an absolute path) is no longer read or listed, and a[lib]/[[bin]]path that leaves it is no crate root.Root cause
rustPathTarget) stopped at the type:Type::memberpaths fell to qualified-name matching, which takes anyItemPool::for_def, a decoy crate's included.variable, the kind apub const/staticis extracted as.getCargoWorkspaceCrateMapread<member>/Cargo.toml(and listed a glob member's directories) for every member as written,../outsideincluded; only dependency paths were kept inside the project.Fix
rustPathTarget: for a call whose second-to-last segment is a type (CamelCase), the type is the item the path's modules name (rustUsePathItems), or, written alone, the one the visibleuseof its name names (rustUseItemsAt).rustTypeMemberthen finds the member: an enum's variant; else the type's inherent function orconstin the type's own crate (a trait impl's only when it is the one of that name, asmatchRustSelfPathpicks); a trait's own declared method. A type alias,Self, a type the module declares itself and type paths in other positions are left as they were.RUST_PATH_ITEM_KINDSincludesvariable(module-level only:rustDeclaredItemsnever returns an impl'sconst).matchRustUseBoundNamereads a qualifier written on the line above a bare type (rust-scopes' blanked code, so// crate::scheduler::is none) and resolves the whole path.escapesRoot(fix(paths): a folder named like ..generated is inside the project, not outside it #3028's helper):expandMembersskips a member that leaves the project before reading or listing anything for it;rustCrateGraphpasses members and[lib]/[[bin]]paths through the samejoinits dependency paths use, which now asksescapesRoottoo and drops one that leaves the project. A member whose folder only starts with two dots (..generated/crate) is still read.Validation
Tests: fix(rust): resolve paths into other crates of a Cargo workspace #2631's
rust-cross-crate.test.ts(9 cases, credited),rust-type-member-paths.test.tsandrust-manifest-paths.test.ts: on main 10 of 15 fail; all pass. Everyrust-*suite passes. On main, a workspace listing../outside,../vendor/*and/abs/crateread../outside/Cargo.toml,../vendor/x/Cargo.tomland/abs/crate/Cargo.tomland listed../vendor; with the fix it reads only the project's manifests.A/B against main (4955eac, with fix(rust): use bindings follow Rust's scopes, and module paths walk the crate's modules #3014; re-checked on 60b0d7a and cdfa31b, each with its own kernel), 7 Rust repos, native kernel; every site the same as against fix(rust): use bindings follow Rust's scopes, and module paths walk the crate's modules #3014's own commit:
Retargets, all checked: tokio's
Semaphore::new(66) frombatch_semaphore.rsto thesync::Semaphorethe code imports,RwLock/Mutex/Barrier::new(55) from loom mocks totokio::sync's, a taskBuilder::new(9) from tokio-test's io builder,Wheel::new/ReusableBoxFuture::new/Elapsed::newfrom tokio-util's and tokio-stream's namesakes to tokio's own; ripgrep'sError::fromfrom grep-cli'sErrorto ignore's own,RegexMatcherBuilder::new()from pcre2's to grep-regex's; dioxus'sCssAssetOptions::default()to the inherentconst fn defaultRust picks over theDefaultimpl; gleam'sPrinter::new(45) fromdocs/printer.rsto thetype_::printer::Printerthe files import. Additive sites are chains gaining their head call (Builder::new_current_thread().build(),clap::Arg::new("x").short(…)). Added sites sampled (all right) and every target's crate checked against the manifests. express and flask byte-identical. The manifest change moves nothing in these repos (none lists a member outside itself).Cost (native kernel, medians of 3 interleaved runs; dioxus of 7, as its spread was widest):
Timed on one thread (resolver pool off), dioxus's
rustPathTargettakes 1.32 s against main's 1.24 s over the same 17,198 calls, andrustTypeMember15 ms;isRustNameInScopeandmatchRustUseBoundNameare unchanged.Full suite (native kernel rebuilt from main,
CODEGRAPH_KERNEL_EXPECT=1, daemon allowed, 4 workers) on this commit, on cdfa31b: 805 files (799 passed, 6 skipped); 9,629 tests: 9,543 passed, 0 failed, 86 skipped.Left out
Semaphore::MAX_PERMITS) are not extracted as path references at all, so they gain nothing here.Type::memberpath whose type the module declares itself (Foo::new()besidestruct Foo) keeps main's resolution; so does a type alias's.#[path]modules are fix(rust): resolve use super::* callees in #[path] modules #1892's follow-up, stacked on this one.🤖 Generated with Claude Code