Summary
When an interface-typed variable is declared in one place, assigned a local concrete type inside one closure, and called inside another closure, the call currently has no proper source attribution and (under receiver-qualified QNs, #1913) no target at all. Before writing a fixture the target representation has to be decided; this issue records that decision.
Corpus shape (kubernetes, test/e2e/apimachinery/crd_validation_ratcheting.go)
:48 — var restmapper meta.RESTMapper
:74 — restmapper = &fakeRESTMapper{...} inside a ginkgo.BeforeEach closure
:93 — restmapper.KindFor(gvr) inside a different closure (applyPatch)
:913 — func (f *fakeRESTMapper) KindFor(...)
Today the edge is crd_validation_ratcheting.go.__file__ -> ...apimachinery.KindFor — source is the File node, not a function, and the target is a same_module flat-QN hash (pkg.KindFor, 0.9, cand=1), i.e. a name coincidence, not a resolution. Under receiver-qualified QNs there is no row.
Decision: the CALLS target is the interface member
meta.RESTMapper.KindFor — the static dispatch target. Rationale: go_lsp.c already routes registered interface receivers deliberately to the interface-resolution branch ("Registered interface receivers must reach the interface-resolution branch below"), and the census classification ratified interface members as the correct static target for the same idiom (informers.Core -> factory.go:355). Resolving to the sole concrete implementer instead (fakeRESTMapper.KindFor) would be higher-precision on test doubles but diverges from the interface-first rule everywhere else in the graph.
What the fix needs
- Source attribution: the call inside the closure must be attributed to the enclosing function (or the closure node), not to
__file__.
- The declared type of
restmapper must survive across closures. go_invalidate_control_flow_aliases (go_lsp.c:1396) exists precisely to discard reassigned bindings — a declared interface type should not be invalidated by a concrete assignment, because the interface is the static type regardless of what is assigned.
- Fixture: three closures in one file mirroring the shape above; assert
applyPatch -> meta.RESTMapper.KindFor and the absence of a __file__ source.
Summary
When an interface-typed variable is declared in one place, assigned a local concrete type inside one closure, and called inside another closure, the call currently has no proper source attribution and (under receiver-qualified QNs, #1913) no target at all. Before writing a fixture the target representation has to be decided; this issue records that decision.
Corpus shape (kubernetes,
test/e2e/apimachinery/crd_validation_ratcheting.go):48—var restmapper meta.RESTMapper:74—restmapper = &fakeRESTMapper{...}inside aginkgo.BeforeEachclosure:93—restmapper.KindFor(gvr)inside a different closure (applyPatch):913—func (f *fakeRESTMapper) KindFor(...)Today the edge is
crd_validation_ratcheting.go.__file__ -> ...apimachinery.KindFor— source is the File node, not a function, and the target is asame_moduleflat-QN hash (pkg.KindFor, 0.9,cand=1), i.e. a name coincidence, not a resolution. Under receiver-qualified QNs there is no row.Decision: the CALLS target is the interface member
meta.RESTMapper.KindFor— the static dispatch target. Rationale:go_lsp.calready routes registered interface receivers deliberately to the interface-resolution branch ("Registered interface receivers must reach the interface-resolution branch below"), and the census classification ratified interface members as the correct static target for the same idiom (informers.Core -> factory.go:355). Resolving to the sole concrete implementer instead (fakeRESTMapper.KindFor) would be higher-precision on test doubles but diverges from the interface-first rule everywhere else in the graph.What the fix needs
__file__.restmappermust survive across closures.go_invalidate_control_flow_aliases(go_lsp.c:1396) exists precisely to discard reassigned bindings — a declared interface type should not be invalidated by a concrete assignment, because the interface is the static type regardless of what is assigned.applyPatch -> meta.RESTMapper.KindForand the absence of a__file__source.