GitNexus/gitnexus/bench/scope-capture
Gergo Magyar a4002c3c43 fix(go): drop the phantom read site on a member call's callee (#2766)
Found by a three-agent investigation into an A1 regression. The
regression was the symptom; this is the disease, and it SHIPPED on this
branch.

Go's `@reference.read` pattern matches every `selector_expression` with
no call-position exclusion, so `h.dep.Work()` minted THREE sites:

  call  Work  on the call_expression          — the member call
  read  Work  on the outer `h.dep.Work`       — PHANTOM, this is the callee
  read  dep   on the inner `h.dep`            — the genuine field read

The phantom resolves through `findOwnedMember`, which prefers methods
over fields, and emits an ACCESSES edge to the METHOD duplicating the
CALLS edge at the same position.

MY U8 CLAIM WAS WRONG. I asserted that typing the base made the ACCESSES
"correctly retarget to the property". It did not. The property edge was
always a separate site, and the U8 test passed by ACCIDENT: the row it
asserts on has a pointer receiver whose text-cascade lookup failed for an
unrelated reason. The value-receiver twin was emitting the bad edge the
whole time — verified on the pushed branch:

  ACCESSES  RunFromValueReceiver -> DoWork:Method
  ACCESSES  RunLocal             -> DoWork:Method

A selector in FUNCTION position is never a read. Dropped at the emitter.
A method VALUE (`f := h.dep.Work`) is not in function position and is
untouched.

Deliberately NOT fixed by gating on `handledSites`: the three co-located
Go sites share one site key, so that would suppress the correct
`RunSamePackage -> dep` edge depending on match order. Nor by flipping
`findOwnedMember` to prefer fields on reads — that is cross-language and
would break legitimate method-value reads.

The weak assertion is replaced by an exact-set check over the whole
fixture, so a new phantom fails even on a row nobody wrote a targeted
assertion for. My first attempt at that check compared `undefined ===
undefined` and would have passed against anything; caught and rewritten.

Numbers:
  callDrops   102 -> 102   no call lost
  read drops   27 ->  22   five phantoms were being RECORDED AS DROPS
  chain-field  61 ->  60   one reclassified...
  chain-unwrap  0 ->   1   ...to the real call's shape, because the
                           phantom and the call share a site key and the
                           phantom's chain was the one being censused

Baselines: go scope-capture fingerprint and the go capture golden
rebaselined with reasons — fewer capture matches for Go, and go was the
only fingerprint of 15 that moved, which is the check that this touches
Go's emitter alone. 4369 tests green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 16:28:34 +00:00
..
baselines.json fix(go): drop the phantom read site on a member call's callee (#2766) 2026-08-01 16:28:34 +00:00
measure.mjs fix(java): JLS binary-name identities for local classes, enums, records & interfaces (#2562) (#2653) 2026-07-24 11:58:53 +01:00