Repository navigation
fix(rust): use bindings follow Rust's scopes, and module paths walk the crate's modules - #3014
Merged
Merged
Conversation
…he crate's modules
A bare Rust name took the file's `use`s all at once: a `use` inside one
function (`fn first() { use crate::util::take; take() }`) bound `take` for
every other function too, and for the file's own `fn take`; a renamed one
(`use crate::util::take as consume; consume()`) linked nothing, since no
item carries the alias; a parameter or closure of the function's name
(`fn run(take: fn()) { take() }`, `let take = || {};`) linked to the
imported function; and `use crate::models::E::Good; Good(1)` took any
`E::Good`. Paths through modules (`resolveRustPathReference`) walked the
directories instead of the modules: `super::helper()` and `crate::config()`
with no module between linked nothing, `super` inside an inline
`mod tests { }` went to the parent directory's module, and an item a module
passes on (`pub use`, a glob) or another workspace crate's was not found.
The fix keeps one `use` reader, rustUsesOf:
- each `use` keeps the block it is written in (a function's body or a
block; an inline `mod` and a macro's braces, `cfg_if!`'s nested ones
included, are the module's), and std `use`s are kept by position;
- a reference reads the binding of its innermost scope (rustVisibleUse);
isRustNameInScope uses it, so a block's `use` shadows the file's own item
and a variant `use` names its enum's variant (rustUsePathItems' enum tail);
- matchRustUseBoundName, ahead of the pre-filter, resolves a rename to the
item its path names, and a call to a name a local binds (rust-scopes'
bindings, nearer than any `use`) to nothing, unless the local is a `let`
holding a function by its path (serde's `let test = test::<i8>;`);
- resolveRustPathReference is rustWalkModules + rustModuleItems from the
module the path is written in (rustPathTarget), with today's crate-root
fallback; resolveRustModuleFile, collectRustUseBindings and
rustItemPlacement are gone, and isBoundToOutOfRepoImport reads
rustUsesOf's std `use`s;
- `use`s are read with strings blanked (blankRustCode), so a string's
"use crate::x;" binds nothing;
- the crate graph reads a package's name by its section (axum-core writes
`categories = [..]` first) and a `[lib]`/`[[bin]]` path of its own
(ripgrep's `crates/core/main.rs`), which `crate::` then starts from; a
file no manifest covers starts it from the nearest lib.rs or main.rs
above it, as the directory walk did.
Validation:
- rust-use-call.test.ts (PR 2308's 15 cases), rust-use-scopes.test.ts,
rust-crate-roots.test.ts and 5 new rust-module-path-call cases: on main's
source 18 of 32 fail; all pass. Every rust-* suite passes.
- A/B on main 01e0ac3, 7 repos, the same sites on the kernel and on wasm:
tokio +2,434 sites (1,354 calls, 1,053 imports), 159 removed (152 locals
called or passed as values, 6 `Result`s std's, 1 import through a path
attribute module); ripgrep +248 / -149; axum +710 / -60; clap +730 / -112;
serde +155 / -207 (192 calls to a closure named `test`); dioxus
+2,950 / -272; gleam +1,573 / -359. Groups and samples inspected, every
changed site's crate checked against the manifests' dependencies;
express and flask byte-identical.
- Cost (kernel, medians of 3 interleaved): tokio CPU 34.5 -> 33.0 s, peak
RSS 991 -> 1,007 MB; gleam 32.5 -> 30.6 s, 1,022 -> 1,012 MB; dioxus
45.4 -> 45.4 s, 1,101 -> 1,107 MB.
- Original PR #2308 by @danusha2345; its module-path part landed as PR #2955.
Co-authored-by: danusha2345 <ewidusoc498@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
colbymchenry
force-pushed
the
claude/rust-use-bindings-on-main
branch
from
October 29, 2026 17:26
c55fd60 to
40e6e19
Compare
This was referenced Oct 29, 2026
inth3shadows
added a commit
to inth3shadows/codegraph
that referenced
this pull request
Oct 29, 2026
Brings 4955eac..787eafb (colbymchenry#3014, colbymchenry#3017, colbymchenry#3020, colbymchenry#3018, colbymchenry#3023). Clean auto-merge. README: drop colbymchenry#2871 (closed upstream; colbymchenry#2934 merged in its place, and name-matcher already matches upstream).
colbymchenry
added a commit
that referenced
this pull request
Oct 29, 2026
…'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 (isInsideProject, 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 11 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 57dc7ae): 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
added a commit
that referenced
this pull request
Oct 29, 2026
…'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 a38a1ec): 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
added a commit
that referenced
this pull request
Oct 29, 2026
…'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 a38a1ec): 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
added a commit
that referenced
this pull request
Oct 30, 2026
…'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 a38a1ec): 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
added a commit
that referenced
this pull request
Oct 30, 2026
…'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>
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 #2308 by @danusha2345 (its module-path part landed as #2955): Rust
usebindings now follow Rust's scopes, on main's ownusemodel instead of a second parser.use(use crate::util::take as consume; consume()) links to the item its path names.usewritten in a function or a block binds its name there only, ahead of the module'suses and the file's own items.letof a function's name links to nothing, not to the function; aletholding a function by its path (let test = test::<i8>;) calls that function.use crate::models::E::Good; Good(1)links to that enum's variant.resolveRustPathReference) walk the crate's modules (rustWalkModules+rustModuleItems) from the module they are written in:super::x()/crate::x()with no module between,superinside an inlinemod tests { }, items passed on withpub useor globs, and other workspace crates by the names their manifests give them.Root cause
isRustNameInScopetook everyuseof a name in the file (rustUseItems), wherever it was written, and only items carry names, so a rename had nothing to match.resolveRustPathReferencemapped a path to a file by directory (resolveRustModuleFile), so a path with nothing betweensuper/crateand its item had no file,superin an inline module went to the directory's parent, and re-exports and other crates were never followed.Fix
usereader,rustUsesOf: eachusekeeps the block it is written in (rust-scopes-style braces; an inlinemodand a macro's braces,cfg_if!'s nested ones included, are the module's), stduses are kept with their positions, and the text is read with strings blanked (blankRustCode), so a string's"use crate::x;"binds nothing.rustVisibleUse: the innermost scope's bindings at a reference.isRustNameInScopeuses it (rustUseItemsAt), falling back to the whole file's when nothing binds the name there.matchRustUseBoundName, ahead of the pre-filter: renames, and locals viarust-scopes'rustBindingAt(a nestedfnsees none of its parent's; a block'susenearer than the local wins).rustUsePathItems: an enum parent's variant.rustPathTarget(behindresolveRustPathReference): the module walk, with today's 2015 crate-root fallback; aType::memberpath is skipped here (as before, it names no module item).rustCrateGraph: package names read by section (axum-core writescategories = [..]beforename; the crate was missing from the graph), and[lib]/[[bin]]paths of their own (ripgrep'scrates/core/main.rs), whichcrate::starts from. A file no manifest covers (sources indexed without theirCargo.toml) startscrate::from the nearestlib.rs/main.rsabove it, as the directory walk did (extraction.test.ts's manifest-lessdatabase::profiles::find()case).resolveRustModuleFile,collectRustUseBindings(isBoundToOutOfRepoImportnow readsrustUsesOf's stduses),rustItemPlacement.Validation
Tests: PR fix(rust): resolve bare calls through exact use bindings #2308's
rust-use-call.test.ts(15 cases, credited), newrust-use-scopes.test.ts(its parser-level scenarios as call edges, plus held functions and macro braces),rust-crate-roots.test.ts, and 5 newrust-module-path-callcases. On main's resolution source 18 of the 32 fail; with the fix all pass. All 34 Rust-related suites pass (292 tests).A/B on main (01e0ac3; re-checked on 13f983d and 86c85cf), 7 Rust repos, the same sites on the native kernel and on wasm:
mpsc::channel,task::spawn→ tokio-test's,tokio::task::yield_now), +1,053 imports; removed: 152 locals passed or called, 6 stdResults, 1 import through a#[path]modulebuild(matcher, searcher, printer)), a block'suse std::os::unix::fs::symlinkRequestunderuse http::RequestClapResult/ClapErrorrenames now link; removed: localslet test = |value, tokens| test(…)(its body keeps the edge)Ok(…)main took for dioxus-core'sfn Okvia auseread from a stringErrorfrom a framework guess to theusederror::ErrorenumTriage: every group inspected with samples (all right); every added or moved target's crate checked against the source crate's manifest dependencies (the only cross-direction ones are trait → implementation edges). express and flask byte-identical. Known loss: tokio's
use crate::process::unix::GlobalOrphanQueue, whereunixpasses onsuper::imp::*andimpis one of two cfg-alternative#[path]modules (unix/mod.rs,windows.rs); main found it by the directory's name, and a module that depends on the build stays unread (fix(rust): resolve use super::* callees in #[path] modules #1892's follow-up keeps it so).Cost (kernel, medians of 3 interleaved runs):
(A first version walked every
Type::memberpath too and cost ~40 MB on tokio; such paths now skip the walk, since they name no module item.)Full suite (kernel,
CODEGRAPH_KERNEL_EXPECT=1, daemon allowed, one worker) on this commit, on e7c9ffd: 784 files (778 passed, 6 skipped); 9,366 tests: 9,281 passed, 0 failed, 85 skipped.Left out
use a::b as c;emits no import node or ref in either extractor (only one inside a{ … }group does), so such ausestill has no import edge; that is an extraction change.uses are scoped.Type::memberpaths,pub const/staticitems and cross-crate type paths are fix(rust): resolve paths into other crates of a Cargo workspace #2631's follow-up;#[path]modules are fix(rust): resolve use super::* callees in #[path] modules #1892's.🤖 Generated with Claude Code