Skip to content

fix(rust): scope-resolution coverage gaps — F66,F68,F71,F72 (#1934)#1974

Merged
magyargergo merged 7 commits into
abhigyanpatwari:mainfrom
prajapatisparsh:fix/rust-parsing-coverage
Jun 3, 2026
Merged

fix(rust): scope-resolution coverage gaps — F66,F68,F71,F72 (#1934)#1974
magyargergo merged 7 commits into
abhigyanpatwari:mainfrom
prajapatisparsh:fix/rust-parsing-coverage

Conversation

@prajapatisparsh

@prajapatisparsh prajapatisparsh commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Closes the #1934 Rust scope-resolution coverage gaps.

F66/F68 — let-binding patterns: let_declaration captures pattern:(identifier) (covers let x / let mut x); destructuring shapes are intentionally excluded — capturing (_) would register an unreferenceable whole-pattern name ("(a, b)").

F71 — unions: union_item is materialized as a Struct-labeled node and is resolvable (the union literal is a real constructor). Every registry-primary resolution gate includes Struct but excludes Union, so Struct is the resolvable + honest label; rationale documented inline. Also added the missing union_item arm to the legacy RUST_QUERIES so the node actually exists.

F72 — macros (fully wired): macro_rules! definitions are captured (@declaration.macroMacro) and macro invocations (@reference.macro) resolve via a dedicated MacroRegistry (acceptedKinds: ['Macro']) to the macro definition, emitting a USES edge to the Macro node. Because the registry only accepts Macro defs, a macro invocation can never bind to a same-named free function — macros and functions stay disjoint namespaces (the false-CALLS-edge class flagged in review). Scoped macro invocations capture the tail identifier (log::info!info).

F73 — dropped (variadic was never implemented; removed from the title + baselines note).

Tests: parity-gated pipeline-level union + macro resolution in rust.test.ts; capture-layer regressions in rust-coverage.test.ts; new rust-macro / rust-union fixtures. Rust capture golden + scope-capture fingerprint rebaselined (~0.99 linear).

F67/F69/F74 already closed by #1937/#1940/#1956.


Maintainer follow-up (review of #1974): merged latest main, rebaselined, and addressed the review threads — fully wiring F72 per the review's option (a).

@vercel

vercel Bot commented Jun 2, 2026

Copy link
Copy Markdown

@prajapatisparsh is attempting to deploy a commit to the NexusCore Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

CI Report

All checks passed

Pipeline Status

Stage Status Details
✅ Typecheck success tsc --noEmit
✅ Tests success unit tests, 3 platforms
✅ E2E success gitnexus-web changes only

Test Results

Tests Passed Failed Skipped Duration
10953 10940 0 13 671s

✅ All 10940 tests passed

13 test(s) skipped — expand for details
  • COBOL pipeline benchmark > scales with file count
  • C# pipeline benchmark > scales with file count — namespaces spread across the solution
  • C# pipeline benchmark > scales with file count — all types in one (global) namespace bucket
  • C# pipeline benchmark > scales with file count — all types in one (named) namespace bucket
  • Go pipeline benchmark > scales with file count (workers enabled)
  • Go pipeline benchmark — worker pool (issue Worker idle timeout kills long Go scope extraction and surfaces as Napi::Error during analyze #1848) > does not quarantine the large generated Go file on sub-batch idle timeout
  • Go structural interface detection benchmark > scales linearly with interface × struct count
  • Go structural interface detection split-phase benchmark > separates index-build and detection time
  • PHP pipeline benchmark > scales with file count (workers enabled)
  • Ruby pipeline benchmark > scales with file count (workers enabled)
  • Rust pipeline benchmark > scales with file count (workers enabled)
  • run.cjs direct-exec entrypoint (fix(cli): steer docs, skills, and hooks through a CLI-neutral project-local runner (#1939) #1945) > resolves a .cmd shim via the Windows shell branch, passing args and exit code
  • buildTypeEnv > known limitations (documented skip tests) > Ruby block parameter: users.each { |user| } — closure param inference, different feature

Code Coverage

Tests

Metric Coverage Covered Base Delta Status
Statements 80.3% 38245/47625 79.84% 📈 +0.5 🟢 ████████████████░░░░
Branches 68.85% 24321/35320 68.5% 📈 +0.3 🟢 █████████████░░░░░░░
Functions 85.45% 3978/4655 84.94% 📈 +0.5 🟢 █████████████████░░░
Lines 83.91% 34403/40998 83.36% 📈 +0.5 🟢 ████████████████░░░░

📋 View full run · Generated by CI

@magyargergo magyargergo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Tri-Review — #1974 fix(rust): scope-resolution coverage gaps — F66,F68,F71,F72,F73 (#1934)

Verdict: not production-ready. Two of the five claimed gaps don't land as intended and one introduces a new false-edge class in the call graph. Branch hygiene: clean fork feature branch (no merge churn beyond a main merge). Merge state: BLOCKED on required review; CI: substantive jobs pending on the just-pushed head (Python/autofix/gitleaks/review pass; the Vercel fail is fork-auth, not a defect).

Methods & engines (read first). Genuine three-method review: Codex (gpt-5.5, the one independent engine — live; it reviewed via the GitHub connector since its local shell was unavailable) + GitNexus swarm + Compound-Engineering personas. Four Claude lanes returned full findings (correctness, adversarial, testing, plus the coordinator's own reproductions); the risk-architect and test/CI lanes ended mid-investigation, their domains covered by the others. Independence is asymmetric — most lanes are Claude under different prompts. Codex independently corroborated findings 2 and 3 below (strong); the headline (finding 1) is adversarial-only, so the coordinator reproduced its trigger + resolver path directly.

Headline (P1 — adversarial + coordinator-verified): macro invocations create false CALLS edges to same-named functions

The new F72 arms route macro_invocation through @reference.call.free with the macro's bare name. Rust macros and functions occupy disjoint namespaces, but the free-call resolver doesn't: a log!(…) invocation emits a free-call reference named log with arity=undefined; free-call-fallback.ts:167 resolves that name to a same-named fn log and :390 emits a CALLS edge (confidence ~0.85), and rustArityCompatibility returns unknown for undefined arity so no arity guard rejects it. Net: invoking log! produces a graph edge caller → fn log that the code never calls. The adversarial lane reproduced the materialized edge end-to-end via the full pipeline (caller → log same-file and run → assert cross-file); the coordinator independently reproduced the trigger (log!("hi")@reference.call.free name="log" arity=undefined alongside fn log@declaration.function) and code-read the resolver path. Before this PR, macros emitted no reference (clean miss), so this is a newly introduced false-positive class that degrades exactly the call-graph/impact-analysis accuracy GitNexus exists to provide. Blast radius: any Rust repo where an invoked macro name matches a free function name (common with macro_rules! helpers). Fix: tag macros distinctly (suffix !, or a dedicated @reference.macro) and do not route them through free-call CALLS resolution. [reproduced]

Inline findings

  • [P1] query.ts:132-133 — macro→function false CALLS edge (above). [reproduced]
  • [P2 · Codex + correctness + adversarial] query.ts:53let_declaration pattern: (identifier)pattern: (_) (and the five @type-binding.* arms) makes @declaration.name/@type-binding.name capture the whole pattern node text for any non-bare pattern: let (a, b) → name "(a, b)", Some(val)"Some(val)", Foo { field }"Foo { field }", ref z"ref z", n @ 1..=10"n @ 1..=10" (coordinator-reproduced via emitRustScopeCaptures). So F66/F68 is not actually delivered for destructuring/ref/captured patterns — the binding is registered under an unreferenceable name no a/b/val/field/z lookup can ever hit, and the same bogus name propagates to the type-binding arms. It's currently inert at the graph level (the legacy DAG still owns let-binding nodes, so these don't materialize as symbols — verified) but pollutes the in-memory scope index and is baked into the golden + tests as "expected". It touches ~12 existing fixtures (golden captureGroups +1/+2). Fix: extract the inner identifier(s) (one binding per bound name) or restrict the arms to identifier-bearing shapes; don't capture whole-pattern text as a name. [reproduced]
  • [P2 · Codex + correctness + adversarial + testing] query.ts:72 — the F73 (variadic_parameter pattern: (_)) arm is dead (tree-sitter-rust's variadic_parameter ... has no pattern field → 0 matches; verified), and the captures.ts:277 arity change can't fire for real variadics (extern fns are function_signature_item, never the function_item the query captures). The F73 test (rust-coverage.test.ts:108, params.length >= 1) false-passes via the unrelated fmt parameter, so deleting the dead arm wouldn't fail it. Fix: capture the variadic marker structurally and rewrite the test to assert something only the variadic produces (or drop the dead arm). [reproduced]

Lower-priority / body-only

  • [P3] Scoped-macro arm is dead coverage (query.ts:135-136): macro: (scoped_identifier) captures the full path (std::println / foo::bar) as the name, which resolves to nothing — so scoped macros aren't covered (and dodge the false-edge above only by accident). Untested. [reproduced by adversarial]
  • [P2 test-quality] Tests/golden bless the bogus names. The destructuring tests assert only vars.length === 1 (never the name); the let ref x test codifies @declaration.name === 'ref x' with a comment acknowledging it's the pattern text, not the variable; and the captures-golden hashes capture text into its digest, so "(a, b)"/"ref x" are locked in as the expected baseline. A reviewer can't see from the golden that wrong names were introduced. [code-read]
  • [P3] captures.ts:277 arity counts a ... as one required+max parameter — semantically wrong for a variadic if it ever fired (it can't, for valid Rust). [code-read]

Validated / refuted (validation is a feature)

  • F71 union (@scope.class + @declaration.struct name "MyUnion") and bare-identifier F72 macros (println/vec) work correctly — verified. The macro arms are written as separate specs (not a […] alternation), correctly avoiding the tree-sitter-0.21 alternation-predicate hazard that bit prior PRs.
  • No symbol shadowing/collision from the bogus names — they contain ()/{}/@/spaces and can never collide with a valid Rust identifier (Codex + correctness + adversarial agree). let _ = x does not create a "_" binding (refuted). Two identical let (a, b) don't collide on nodeId (refuted). The bogus let bindings are not materialized as graph nodes today (refuted graph corruption). The change is correctly Rust-provider-scoped (languages/rust/), honoring the no-language-names-in-shared-code rule.

Test gaps

  • No test asserts a destructured identifier (a/val/x) actually resolves — only capture counts. The F73 test proves nothing about the variadic arm. The scoped-macro arm and the captures.ts arity change have no real assertion. No regression test asserts the absence of the macro→function false edge.

Automated multi-tool digest (Codex gpt-5.5 + GitNexus swarm + Compound-Engineering personas). Verify before acting; the P1 macro-edge is adversarial-only + coordinator-reproduced, not independently cross-engine.

Comment thread gitnexus/src/core/ingestion/languages/rust/query.ts Outdated
Comment thread gitnexus/src/core/ingestion/languages/rust/query.ts Outdated
Comment thread gitnexus/src/core/ingestion/languages/rust/query.ts Outdated

@magyargergo magyargergo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #1974 Tri-Review (local, not posted) — fix(rust): scope-resolution coverage gaps F66,F68,F71,F72,F73 (#1934)

Automated multi-method digest. Local-only — nothing posted to GitHub. Verify the cited file:line evidence before acting.

Method & engine breakdown

Three methods, with honest independence weighting:

  • GitNexus swarm lanes (Claude) — risk, test/CI.
  • Compound-Engineering personas (Claude) — correctness, adversarial, testing.
  • Codex (the only independent engine) — LIVE this run (gpt-5.5, xhigh effort; ran via the GitHub API because local shell was unavailable in its container). Coordinator-confirmed live: the run logged codex live: true and returned 4 substantive, file:line-cited findings that reconcile cleanly with the Claude lanes (no inter-engine disagreement).

Weighting: findings where Codex + a Claude lane independently agree are STRONG; Claude-only agreement is "consistent across personas." The strongest single signal is end-to-end tsx reproduction of the capture-layer behavior (run read-only).

Process notes: The synthesis-critic gate was run; most of its "required corrections" were demands to conform to the gitnexus-pr-swarm-review 12-section template, which is a different skill's rubric — not adopted. Its substantive points were applied (F72 severity reconciled to P2; scoped-macro retagged [code-read]). One critic should-fix was itself wrong (CALLABLE_OR_TYPE_LIKE does exist — verified). Two earlier gitnexus-* lane runs truncated; their domains are covered by lanes that completed.

Scope reality-check (title vs. what actually lands)

The single production file is gitnexus/src/core/ingestion/languages/rust/query.ts (+19 lines of tree-sitter scope-query patterns).

Claimed Reality Status
F66/F68 let-binding patterns pattern:(identifier) correctly captures let x / let mut x, excludes destructuring ✅ Lands correctly
F71 union union_item tagged @declaration.structStruct node (not Union); pragmatic/benign, untested at pipeline layer ⚠️ Lands, with a nuance
F72 macro @reference.macro fires at the query layer but is dropped downstream → zero graph edges ❌ Silent no-op
F73 variadic Dropped in commit 93e4096f; no impl/test/fixture ❌ Absent — title over-claims

Net: the PR delivers less than the title states. F66/F68 are real; F71 is real but mislabeled & unverified end-to-end; F72 is inert; F73 does not exist.

Findings (severity order)

P2 (headline) — F72 macro coverage is a silent no-op · STRONG (Codex P1/0.99 + correctness + adversarial + risk) · [reproduced] + [code-read]

query.ts:127-132 emits @reference.macro, but it is discarded downstream:

  • scope-extractor.ts:990-991const kind = referenceKindFromAnchor(anchor.name); if (kind === undefined) continue;
  • scope-extractor.ts:1027-1049referenceKindFromAnchor has no macro branch (only call/read/write/type/inherits/import-use) → returns undefined.
  • gitnexus-shared/src/scope-resolution/reference-site.ts:34-40ReferenceKind has no macro member.
  • No consumer of @reference.macro exists anywhere in src.

Reproduced (tsx): raw captures fire (['println','vec','log::info']) but every one is dropped at pass5CollectReferences0 ReferenceSites, 0 graph edges for any macro. Macro calls were invisible before this PR and remain invisible after.

Severity note: Codex rated this P1 (conf 0.99); I down-weight to P2 because it is not a runtime regression — nothing that worked breaks. It is the PR's most important issue because it silently fails to deliver a stated feature while a green test implies otherwise.

P2 — F72 test is capture-layer-only false confidence · STRONG (Codex + testing + risk) · [reproduced] + [code-read]

test/integration/resolvers/rust-coverage.test.ts:50-66 asserts only that @reference.macro appears in raw emitRustScopeCaptures output — never a ReferenceSite, graph edge, or usage node. It passes green because the capture layer fires, while the pipeline emits nothing. A reader of the test (titled "F72 — macro invocations") will believe macro resolution works.

P2 — Title and baselines.json over-claim F73 (variadic) · STRONG (Codex + risk) · [code-read]

F73 was explicitly dropped in commit 93e4096f ("drop variadic"); no impl/test/fixture remains. Yet the PR title still reads …F72,F73, and gitnexus/bench/scope-capture/baselines.json _note still says "…F72 macro, F73 variadic…". Audit-trail integrity problem (a future bisect for "when was F73 closed?" is misled). Fix: drop F73 from the title and the _note (or re-implement).

P2 — union_item@declaration.struct: pragmatic/benign but untested & undocumented · STRONG-agree on mechanism · [reproduced] + [code-read]

query.ts:35-36 tags the union @declaration.struct → a Struct-labeled SymbolDefinition. This is deliberate and benign, not a defect:

  • scope-extractor.ts:703-714normalizeNodeLabel supports 'union'→'Union', but the query never emits @declaration.union.
  • node-lookup.ts:165-189 (isLinkableLabel) lists Struct/Enum/Trait/… but excludes Union; finalize-algorithm.ts:785-803 (CALLABLE_OR_TYPE_LIKE) includes Struct, excludes Union; class-types.ts:4-7 (ClassLikeNodeLabel) has no Union.
  • A Union-labeled node would be an unresolvable orphan in every registry-primary gate. Struct is the more resolvable label.

Honest framing: the union literal genuinely is a constructor of the type, so the edge a Struct-labeled union yields is correct, not a false edge (correctness + adversarial both refuted the "bug" framing). The real cost is: (a) lost Union/Struct granularity, (b) no comment in query.ts explaining the deliberate downgrade, (c) no pipeline-level test that union.rs resolves to a Struct named MyUnion.

P2 — New test file is excluded from the scope-parity CI gate · consistent across Claude lanes (testing + risk) · [code-read]

.github/workflows/ci-scope-parity.yml runs test/integration/resolvers/<slug>.test.ts; gitnexus/scripts/run-parity.ts:44-45 resolves the Rust slug to rust.test.tsnot rust-coverage.test.ts. The new file runs only in the default vitest sweep, never under the legacy-vs-registry-primary parity gate. Combined with capture-layer-only assertions, F71/F72 get no pipeline-level CI coverage. The golden test catches query-layer drift but not the pipeline-level macro drop.

P3 — Scoped macro captures full path, not tail (latent, inert today) · STRONG (Codex + adversarial) · [code-read] (capture-layer reproduced)

query.ts:131-132macro:(scoped_identifier) @reference.name captures the whole path (log::info), whereas the scoped function-call pattern (query.ts:115-118) captures only the tail name:(identifier). Inert while @reference.macro is dropped, but a correctness bug the moment F72 is wired. Tag corrected to [code-read]: the capture text is reproduced, but the pipeline inconsistency is never observed (macro dropped). Fix: macro:(scoped_identifier path:(_) name:(identifier) @reference.name).

Validated / refuted (credit)

  • VALIDATED [reproduced]: F66/F68 let-pattern narrowing is clean — let x; let mut y; let (a,b); let Some(v); let Foo{field}; let ref r; let n @ 1..=10 yields variable decls ['x','y'] only; no bogus "(a, b)". The explanatory query comment is a genuine quality touch.
  • VALIDATED [reproduced]: (union_item) @scope.class does not over-capture sibling struct/enum bodies (3 separate Class scopes).
  • VALIDATED [reproduced]: macro_rules! defs, attribute macros, and nested macros are not mis-captured.
  • REFUTED (not a defect): union-as-Struct is not a false-edge vector — the union literal is a real constructor; the edge is correct.
  • No regression: new patterns fire only on union/macro nodes; no existing capture renamed/reordered/removed; golden hash updated; no tree-sitter compile hazard (simple field captures, no alternation-predicate hazard); no O(n²) (dropped macro captures do no scope lookup).

Merge-risk verdict: MEDIUM

The lone production change is a pure tree-sitter query-string addition with no runtime logic change and a bounded blast radius (Rust scope extraction only). No working behavior regresses → not HIGH. Not LOW because of three compounding integrity issues (not a production regression): (1) F72 ships as a no-op with a false-confidence test; (2) F73 is claimed in the title + _note but absent; (3) F71 union-as-Struct is correct-but-undocumented with no pipeline test, and the new test file is outside the parity gate.

Recommended conditions before merge: (a) drop F73 from the title and baselines.json _note; (b) either wire F72 end-to-end (add 'macro' to ReferenceKind + a referenceKindFromAnchor branch + a consumer) or document it as capture-only and change the test to assert 0 ReferenceSites for macros; (c) add one pipeline-level assertion that union.rs resolves to a Struct named MyUnion, or document the deliberate Struct downgrade in query.ts; (d) fix the scoped-macro tail-capture (P3) before any F72 wiring; (e) ideally run rust-coverage.test.ts under the parity gate.

Suggested fixes (checklist)

Ordered by priority. Anchors map to the inline comments in pr-1974-review-payload.json.

  • Drop F73 from the PR title + baselines.json _note (or re-implement it) — fastest integrity fix, zero code risk. (C3 · baselines.json:33)
  • Resolve the F72 no-op — either (a) wire macros end-to-end: add 'macro' to ReferenceKind (reference-site.ts:34-40), add a case in referenceKindFromAnchor (scope-extractor.ts:1027-1049), and a consumer that emits the edge; or (b) keep it capture-only: document the intent in query.ts + reference-site.ts and change the test to assert 0 ReferenceSites for macros. (C1 · query.ts:129)
  • Fix the F72 test altitude — assert resolved ReferenceSites/edges (not just raw captures), matching whichever path above is chosen. (C2 · rust-coverage.test.ts:54)
  • Wire rust-coverage.test.ts into the scope-parity gate (or add an equivalent case to rust.test.ts) so F71/F72 get legacy-vs-registry-primary CI coverage. (C2)
  • Document + test the union→Struct choice — a one-line rationale comment at query.ts:36, plus a pipeline-level assertion that union.rs resolves to a Struct named MyUnion. (C4 · query.ts:36)
  • Fix the scoped-macro tail capture before any F72 wiring: macro:(scoped_identifier path:(_) name:(identifier) @reference.name). (C5 · query.ts:132)
  • (nice-to-have) Add negative assertions for the 5 destructuring let shapes in patterns.rs (pin the pattern:(identifier) intent against a future pattern:(_) regression), and a macro_rules!-definition + invocation fixture.

CI / branch / visibility

  • CI (at review time): PASS — lint, typecheck, typecheck-web, tree-sitter-ABI, autofix, gitleaks. PENDING — scope-parity, tests. Vercel "fail" = deploy-auth gate, not a test failure. Note: scope-parity runs rust.test.ts, so a green parity run does not cover rust-coverage.test.ts.
  • Merge state: BLOCKED / MERGEABLE — blocked on pending required checks, no conflicts.
  • Branch hygiene: two Merge branch 'main' commits (622053ae, 03dac44f) present but harmless/merge-safe; no unrelated churn; single-domain (Rust query).
  • Could verify: all cited file:line evidence (re-read), the tsx reproductions, the legacy/gate wiring, Codex liveness. Couldn't verify: pending CI results; full npx gitnexus analyze end-to-end graph output (worktrees can't build — validated via tsx/extract-level instead).

Automated three-method digest (2 Claude method-families + live Codex). High-signal starting point, not a final verdict — verify cited evidence and reproductions before acting.


;; References — macro invocations (disjoint namespace from functions)
(macro_invocation
macro: (identifier) @reference.name) @reference.macro

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2 · headline] F72 macro coverage is a silent no-op. This @reference.macro capture fires at the query layer, but the scope-extractor drops it: referenceKindFromAnchor (scope-extractor.ts:1027-1049) has no macro case so it returns undefined, and pass5CollectReferences (scope-extractor.ts:990-991) does if (kind === undefined) continue;. ReferenceKind (gitnexus-shared/src/scope-resolution/reference-site.ts:34-40) has no macro member, and nothing in src consumes @reference.macro. Net: 0 ReferenceSites / 0 graph edges for any macro invocation — macros are as invisible after this PR as before. Not a regression, but F72 ships inert.

Fix: add 'macro' to ReferenceKind + a referenceKindFromAnchor branch + a consumer, or document it as capture-only and drop the F72 claim from the title.

[reproduced via tsx + code-read; corroborated by Codex (gpt-5.5/xhigh) + correctness/adversarial/risk lanes]

@magyargergo magyargergo Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved by fully wiring F72. Added a 'macro' ReferenceKind + a MacroRegistry: referenceKindFromAnchor now maps @reference.macro'macro', resolve-references routes those sites through the macro registry, the edge mappers map 'macro'USES, and isLinkableLabel makes Macro linkable so the registry def bridges to the legacy @definition.macro graph node. Net: println!() / vec![] / log::info!() now produce real USES edges to their Macro defs. (49d2940)

it('macro_invocation with bare identifier emits @reference.macro', () => {
const src = `fn f() { println!("hi"); }\n`;
const matches = emitRustScopeCaptures(src, 'test.rs') as CaptureMatch[];
const macroRefs = matches.filter((m) => m['@reference.macro']);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Capture-layer-only assertion → false confidence. This asserts only that @reference.macro appears in the raw emitRustScopeCaptures output — never a ReferenceSite, graph edge, or usage node. Because the capture is dropped downstream (see the query.ts macro note), this test passes green while F72 produces nothing in the graph.

Also: this file is not run by the scope-parity CI gate — ci-scope-parity.ymlrun-parity.ts:44-45 resolves the Rust slug to rust.test.ts, not rust-coverage.test.ts, so F71/F72 get no pipeline-level CI coverage.

Fix: assert resolved ReferenceSites/edges (or, if macros stay capture-only, assert 0 ReferenceSites for them), and wire this file into the parity gate.

[reproduced; Codex + testing/risk lanes]

@magyargergo magyargergo Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed. Pipeline-level resolution is now asserted in rust.test.ts (the parity-gated file): the macro resolves to a USES edge on the Macro, with no false CALLS. Macro resolution is registry-primary-only, so the two resolution assertions are listed in LEGACY_RESOLVER_PARITY_EXPECTED_FAILURES['rust'] and skipped under the legacy half (the node-materialization assertion runs on both). The capture-layer tests here are reframed as capture-only and now also pin the scoped-macro tail + the macro_rules! declaration capture. (49d2940)

"scaling_budget": 1.5,
"_rebaselined": "#1956 tri-review U1: rust-qualified-trait fixture (scoped + generic-of-scoped impl trait paths); bareTypeIdentifier now resolves scoped_type_identifier bases by their name: tail (additive, no existing-fixture drift); linear (~1.04)."
"_rebaselined": "#1956 tri-review U1: rust-qualified-trait fixture (scoped + generic-of-scoped impl trait paths); bareTypeIdentifier now resolves scoped_type_identifier bases by their name: tail (additive, no existing-fixture drift); linear (~1.04).",
"_note": "PR #1934: F66/F68 pattern wildcards, F71 union, F72 macro, F73 variadic — fixture count 117→124, fingerprint drift expected."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] F73 is over-claimed. This _note (and the PR title) lists F73 variadic, but F73 was dropped in commit 93e4096f ("drop variadic") — no implementation, test, or fixture remains. A future bisect tracing "when was F73 closed?" will be misled.

Fix: remove F73 variadic from this note and from the PR title (or re-implement F73).

[code-read; Codex + risk lane]

@magyargergo magyargergo Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — F73 removed from the baselines _note and from the PR title (variadic was never implemented; dropped in 93e4096). (49d2940)


;; Declarations — union
(union_item
name: (type_identifier) @declaration.name) @declaration.struct

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Union is labeled Struct, not Union — intentional/benign, but undocumented & untested. @declaration.struct yields normalizeNodeLabel('struct')='Struct'. This is actually the correct pragmatic choice: every registry-primary resolution gate — isLinkableLabel (node-lookup.ts:165-189), CALLABLE_OR_TYPE_LIKE (finalize-algorithm.ts:785-803), ClassLikeNodeLabel (class-types.ts:4-7) — includes Struct but excludes Union, so a @declaration.union node would be an unresolvable orphan. So this is not a bug. But (a) no comment explains the deliberate downgrade, and (b) no pipeline-level test asserts union.rs resolves to a Struct named MyUnion.

Fix: add a one-line rationale comment here, plus a pipeline-level union-resolution test.

[reproduced + code-read; Codex + correctness/adversarial]

@magyargergo magyargergo Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed, and it went deeper than docs: the union had no graph node at all — the legacy RUST_QUERIES never captured union_item, so the @declaration.struct scope capture had nothing to resolve to. Added (union_item name: (type_identifier) @name) @definition.struct to materialize it, plus the rationale comment (Struct chosen because every registry gate includes Struct, excludes Union). New pipeline test rust.test.ts › Rust union resolution asserts union.rs resolves to a Struct named MyUnion and that MyUnion { .. } emits a CALLS edge to it — runs on both parity halves. (49d2940)

macro: (identifier) @reference.name) @reference.macro

(macro_invocation
macro: (scoped_identifier) @reference.name) @reference.macro

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3 · latent] Scoped macro captures the full path, not the tail. macro:(scoped_identifier) @reference.name captures e.g. log::info, whereas the scoped function-call pattern (lines 115-118) captures only the tail name:(identifier). Inert today (the macro capture is dropped — see above), but a correctness bug the moment F72 is wired up.

Fix: macro:(scoped_identifier path:(_) name:(identifier) @reference.name).

[code-read; Codex + adversarial]

@magyargergo magyargergo Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The scoped macro arm now captures the tail identifier: macro: (scoped_identifier name: (identifier) @reference.name), mirroring the scoped free-call pattern — log::info! resolves as info, not log::info. Capture-layer regression added in rust-coverage.test.ts. (49d2940)

@magyargergo

Copy link
Copy Markdown
Collaborator

@prajapatisparsh don't worry I'm looking into this

@magyargergo magyargergo self-assigned this Jun 3, 2026
# Conflicts:
#	gitnexus/bench/scope-capture/baselines.json
@prajapatisparsh

Copy link
Copy Markdown
Contributor Author

@prajapatisparsh don't worry I'm looking into this

I just saw this , I was sleeping 🫠
So u are doing it or i should start working on it ?

@magyargergo

Copy link
Copy Markdown
Collaborator

@prajapatisparsh don't worry I'm looking into this

I just saw this , I was sleeping 🫠 So u are doing it or i should start working on it ?

Yes, there's a tricky path I need to debug for myself. Thanks for this contribution! 👏

…igyanpatwari#1974 review)

Addresses the outstanding abhigyanpatwari#1974 review (second batch). Per maintainer
decision, F72 is FULLY WIRED rather than documented capture-only.

F72 macro — was a capture-only no-op (@reference.macro dropped downstream):
- gitnexus-shared: add 'macro' ReferenceKind + Reference.kind; add
  MACRO_KINDS (['Macro']) and a MacroRegistry that resolves a macro
  invocation ONLY to a macro_rules! definition — never a same-named free
  function (the disjoint-namespace guarantee the review required).
- scope-extractor: referenceKindFromAnchor @reference.macro -> 'macro';
  normalizeNodeLabel 'macro' -> Macro.
- resolve-references: route 'macro' sites through MacroRegistry.
- emit-references / graph-bridge edges: 'macro' -> USES (kept out of the
  CALLS keyspace, which denotes function/method dispatch).
- node-lookup isLinkableLabel: Macro is linkable, bridging the registry
  def to the legacy @definition.macro graph node.
- rust query: capture macro_rules! as @declaration.macro; fix the scoped
  macro arm to capture the tail identifier, not the full path (P3).

F71 union — the @declaration.struct scope capture had no graph node to
resolve to (legacy RUST_QUERIES never captured union_item):
- legacy query: capture union_item as @Definition.struct so the union is
  materialized as a Struct node and is genuinely resolvable.
- query.ts: document the deliberate union->Struct downgrade rationale.

Tests:
- rust.test.ts (parity-gated): pipeline-level union resolution + macro
  resolution (USES to the Macro, exactly one CALLS to fn, none to Macro).
  Macro resolution is registry-primary-only -> listed in
  LEGACY_RESOLVER_PARITY_EXPECTED_FAILURES['rust'].
- rust-coverage.test.ts: scoped-macro tail + macro-def capture assertions;
  reframed as capture-layer only, pointing at the pipeline tests.
- new fixtures rust-macro, rust-union.

F73: dropped from baselines.json _note (variadic was never implemented).

Rebaselined the rust capture golden + scope-capture fingerprint
(a5fdff2c..., scaling ~0.99, fixture_count 126).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@magyargergo magyargergo changed the title fix(rust): scope-resolution coverage gaps — F66,F68,F71,F72,F73 (#1934) fix(rust): scope-resolution coverage gaps — F66,F68,F71,F72 (#1934) Jun 3, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

✨ PR Autofix

Found fixable formatting / unused-import issues across 20 changed lines. Comment /autofix on this PR to apply them, or run npm run lint:fix && npm run format locally.

{"schema":"gitnexus.pr-autofix/v2","state":"fixes-available","pr_number":1974,"changed_lines":20,"head_sha":"49d29403a093fbfb8882af95d6b4a9e0eb63ec02","run_id":"26865684300","apply_command":"/autofix"}

…i#1974)

CI quality/format gate — collapse the multi-line 'macro' addition back to
one line (fits the 100-col print width).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@magyargergo magyargergo merged commit 04ade15 into abhigyanpatwari:main Jun 3, 2026
29 of 30 checks passed
magyargergo added a commit that referenced this pull request Jun 3, 2026
Brings main (78ad6bc) — #1934 rust F71 union / F72 macro, rust-coverage (#1974),
Go interface-impl/type-binding work, hook-resolver changes — into the #1981+#1982
branch (cpp/ruby qualified nested-type identity + resolution-side same-tail fix).

Conflicts resolved (2):
- test/integration/resolvers/rust.test.ts: kept BOTH the #1981 deferred Rust
  same-tail `describe.skip` block AND main's F71 (union) / F72 (macro) describe
  blocks — independent additions at the same location.
- bench/scope-capture/baselines.json: rust fingerprint recomputed for the MERGED
  corpus (main's rust-coverage/F71/F72 fixtures UNION #1981's rust-nested-tail-collision,
  126→127 fixtures) → 56ffc1c0…; cpp/ruby auto-merged (the #1982 fingerprints intact).
  All other entries (reference-site.ts, scope-extractor.ts, helpers.ts, rust golden)
  auto-merged cleanly.

Verified post-merge: tsc clean; bench 14/14 PASS; rust.test.ts 169 pass / 1 skip;
cpp 278 + ruby 142 + 7 capture goldens (479) all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@magyargergo magyargergo linked an issue Jun 5, 2026 that may be closed by this pull request
9 tasks
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.

Rust: parsing-layer coverage gaps (9 findings)

3 participants