Repository navigation
fix: bind Rust module-qualified calls inside the named module via its re-exports - #1034
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughRust qualified-call resolution now follows module paths, scopes, imports, relative prefixes, and recursive re-exports before trie fallback. Tests cover direct modules, re-exports, inline modules, ChangesRust qualified call resolution
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant CallResolver
participant ModulePathResolver
participant ReexportResolver
participant TrieFallback
CallResolver->>ModulePathResolver: resolve qualified module path
ModulePathResolver->>ReexportResolver: follow imports and re-exports
ReexportResolver-->>ModulePathResolver: project-qualified target or unresolved status
ModulePathResolver-->>CallResolver: matched item or decisive module miss
CallResolver->>TrieFallback: fallback for external or unresolved paths
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThe change adds Rust module-qualified call resolution, including direct module items and named or glob re-exports. A compiled Rust fixture confirmed that calls within an inline module can be linked to an enclosing same-named module instead of the inline module’s re-exported functions. Confidence Score: 4/5
What T-Rex did
|
|
Bot reports addressed: Greptile's P1 (inline child-module re-exports losing to an enclosing same-named module) is fixed in eb9e791 with a RED test reproducing its executed fixture. SonarCloud's one new issue (S3776 cognitive complexity 26 on the re-export follow) is resolved in the same commit by extracting the glob expansion into its own function. CodeRabbit had no actionable comments. |
|



Closes #1009.
What
A Rust
module::itemcall whose import probes found nothing fell through to the simple-name trie, which binds an arbitrary same-named function anywhere in the project. ripgrep'smaincallsflags::parse(), whereflags/mod.rsre-exportspub(crate) use crate::flags::parse::{ParseResult, parse};: the re-export sits in the flags module's import mapping (correct since #1007), but resolution never consulted it and emittedmain.main CALLS flags.config.parse, the unrelated config-file parser. That one fabricated edge both marksconfig.parsefalsely live and seversmainfrom the whole flag pipeline, keepingflags.parse.parse,Parser.parse,HiArgs.from_low_argsand transitively the ~926Flagimpl methods dead in the dead-code report even with OVERRIDES present.The fix adds
_try_resolve_rust_module_qualified, consulted after the import probes and before every name-based fallback. The first segment binds where Rust binds it: the caller's inner scopes first (an inline mod's own child module oruseshadows the file's), then the file module'suse(at most one binding per scope is legal, E0255/E0428), then the file's own submodule tree through the same relative-path machinery itsusedeclarations resolve with, so entry files attach submodules beside themselves via the declaring scan and other files nest them.crate::/self::/super::prefixed call paths resolve through the #1007 rewrite machinery too, so the prefixed spellings of the same call bind identically. Ausethat binds the segment to a path outside the indexed project (std, or a workspace crate by name) stops the probe undecided rather than letting the module tree claim a shadowed name.Once a module is decided, the item resolves directly or through the module's own re-exports: named
pub usehops chain as before, Rust 2018 uniform paths (pub use pool::connect;) resolve relative to the owning module, and glob re-exports (pub use m::*;) expand when their base is indexable. An item the module verifiably does not hold is a drop, never a trie guess; a glob whose base cannot be indexed keeps the probe undecided so no edge is dropped on incomplete knowledge. Registered types (Ping::new()) are untouched.Adversarial review
The single pre-push adversarial round found five defects in the first cut, four fixed here with RED tests: glob re-exports and uniform-path re-exports became decided drops (both regressions), inline-mod callers bound the file's same-named module, and the
crate::-prefixed spelling of the issue's own failure mode was untouched. The fifth (ause std::fmt;shadowing a first-party siblingfmtmodule still yields the trie's fabricated edge downstream) is narrowed but not eliminated: the probe now correctly stops undecided instead of authoritatively binding the sibling, and a decided drop there would need workspace crate-name resolution first, since cross-crate calls (use grep_searcher::sinks; sinks::UTF8(...)) are served only by the trie today. Follow-up: #1033.TDD
RED first:
test_rust_module_qualified_calls.pyholds the issue's exact repro (the re-export shape boundconfig.parse, observed failing), a direct submodule call with a same-named decoy (bounddecoy.go, observed failing), the deepflags::defs::build()path, theType::assoc()pinning case, and six review-round repros (crate-glob, uniform-path, and self-glob re-exports, inline-mod shadowing,crate::andself::prefixed spellings), each observed failing before its fix. Full suite: 6707 passed, 10 skipped, against a main baseline of 6697 with the same skips.Summary by CodeRabbit
Bug Fixes
crate::/self::prefixes.Tests