fix(ingestion): own generic Rust inherent-impl methods through the mod-qualified Impl node (#1992)#2003
Conversation
…d-qualified Impl node (#1992) A generic inherent-impl target (`impl<T> Inner<T>`) is a `generic_type` node, which the inherent-impl owner walk (findEnclosingClassInfo) did not match — so the walk returned null and the method got `File -> DEFINES` with NO HAS_METHOD edge (orphaned, and invisible to findDanglingEdges). The Impl node was already correctly mod-qualified (the @name capture drills into the inner type_identifier, tree-sitter-queries.ts), so this is an owner-walk-only fix: drill into the generic base and mirror the node gate so the owner id == the node id byte-for-byte. A scoped-generic target (`impl<T> a::Inner<T>`) materializes no Impl node and is left orphaned (deferred) rather than minting a phantom owner. The owner walk is shared by the sequential and worker paths. New fixture + tests assert positive HAS_METHOD ownership through distinct `a.Inner` / `b.Inner` nodes on both resolver legs and the worker path, plus a negative scoped-generic guard. rust-captures-golden regenerated additively for the new fixture. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tri-review — approveMethod: per-PR multi-lens review → independent adversarial re-verification → static-analysis alignment (tsc/eslint/prettier, all clean) → cross-stack synthesis + critic gate. Review: PR #2003 — Rust generic inherent-impl ownership (#1992)Verdict: Approve ✅ This is a tight, well-scoped, well-tested bugfix. Generic Rust inherent-impl methods ( What I verified (real runtime path)
Strengths
Findings (all minor/nit — none blocking)
Nice work — this is a model targeted ingestion fix with the right test shape. |
CI Report✅ All checks passed Pipeline Status
Test Results
✅ All 11107 tests passed 16 test(s) skipped — expand for details
Code CoverageTests
📋 View full run · Generated by CI |
Operational note: embedding reindex after this stack lands
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…regen rust bench baseline (#1992) F3 follow-up to #1992: two same-tail generic inherent impls under sibling mods that ALSO share a method name (`mod a { impl Inner { fn m } }` + `mod b { impl Inner { fn m } }`) keyed the method node id `${className}.${name}` with the bare tail (`Inner.m`) and collapsed onto one Function node (graph addNode is first-write-wins), silently dropping the second. The owner Impl `classId` was already mod-qualified, masking the collision behind distinct HAS_METHOD sources. Qualify `className` (`a.Inner` / `b.Inner`) in the bare inherent-impl arm so the node id inherits the mod scope; symmetric with the call-resolution fallback, and the HAS_METHOD owner anchors on the unchanged qualified classId. New same-method-name fixture + sequential & worker-parity tests; holds on both legs. Also regenerate the rust scope-capture bench baseline: the new rust-nested-tail-collision-generic (#1992) + rust-generic-impl-same-method-name (F3) fixtures grow the rust-* corpus, so the order-independent fingerprint drifts (56ffc1c0 -> b00aea0f, fixture_count 127 -> 129). Pure fixture-corpus drift — no scope-extractor change; existing fixtures' captures byte-identical. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…me fixture (#1992) The rust-* scope-capture corpus is fingerprinted by TWO gates: the bench baseline (bench/scope-capture/baselines.json, already updated) and the rust-captures-golden unit test (test/fixtures/rust-captures-golden/expected-captures.json). Adding the F3 fixture rust-generic-impl-same-method-name grew the corpus 128->129 entries, so the committed golden drifted too. Regenerated additively (UPDATE_GOLDEN=1) — only the new fixture's entry is added; existing fixtures' captures are byte-identical. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Follow-up to #1981 / #1982.
bc4a560dmod-qualified the unscoped bareimpl Innertarget; a generic inherent-impl target (impl<T> Inner<T>) was not.The Impl node was already correctly mod-qualified for generic impls (the
@namecapture drills into the innertype_identifier,tree-sitter-queries.ts:1226). The defect was in the owner walk (findEnclosingClassInfo): its inherent-impl arm matched onlytype_identifier/scoped_type_identifier, so ageneric_typetarget fell through, the walk returnednull, and the method gotFile → DEFINESwith noHAS_METHODedge — orphaned, and invisible tofindDanglingEdges.Fix
Single site in
findEnclosingClassInfo: match ageneric_typetarget, drill into its base (childForFieldName('type')), and qualify a baretype_identifierbase via the samequalifyRustImplTargetByModScopethe node side uses → owner id == node id byte-for-byte (a.Inner/b.Inner). A scoped-generic base (impl<T> a::Inner<T>) materializes no@definition.implnode, so it falls through with no owner (orphaned, deferred) rather than minting a phantom owner. Node-typed and Rust-impl-gated — no other language reaches theimpl_itemarm; no shared-walker change for other languages.Tests
New
rust-nested-tail-collision-genericfixture + tests:fa/fbown through distinct mod-qualified Impl nodes (a.Inner/b.Inner) — fails pre-fix (methods orphan toFile).fdis not owned through a phantom node (deferred scope-out).usedWorkerPool === true).Verification
rustresolver suite: registry-primary leg 174/174, legacy leg 172 + 2 by-design skips — both green, including the worker path.tsc --noEmitclean; prettier clean.rust-captures-goldenregenerated additively (4 insertions — the new fixture only); scope-capture tripwire unaffected.Closes #1992.
🤖 Generated with Claude Code