Skip to content

go: interface-typed variable assigned a concrete type across closures — CALLS target is the interface member (decision + fixture) #2038

Description

@DeusData

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)

  • :48var restmapper meta.RESTMapper
  • :74restmapper = &fakeRESTMapper{...} inside a ginkgo.BeforeEach closure
  • :93restmapper.KindFor(gvr) inside a different closure (applyPatch)
  • :913func (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

  1. Source attribution: the call inside the closure must be attributed to the enclosing function (or the closure node), not to __file__.
  2. 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.
  3. Fixture: three closures in one file mirroring the shape above; assert applyPatch -> meta.RESTMapper.KindFor and the absence of a __file__ source.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    parsing/qualityGraph extraction bugs, false positives, missing edgestaskUmbrella task grouping multiple related issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions