Skip to content

fix(pipeline): cbm_go_suppress_bare_field_ref's dot-check is inert — the Go guard is a blanket veto, and its census is tautological #1962

Description

@DeusData

Summary

cbm_go_suppress_bare_field_ref (merged in #1944, 20e86c02) drops a reference edge when the target label is Field, the file is Go, and strchr(ref_name, '.') == NULL. The dot test can never be false for Go, so the predicate is a blanket veto on Field-targeted references rather than the precise guard it documents.

Found during post-merge review of the #1937#1940#1944 stack.

Why the dot can never appear

Both call paths strip the receiver before the resolver ever sees the name.

READS/WRITESresolve_lhs_write_name (internal/cbm/extract_semantic.c) documents its own contract:

//   - field/member/selector access (`self.total = ...`, `obj.Field = ...` →
//     write the trailing field name `total`/`Field`)

So t.err = x yields ref_name == "err", never "t.err".

USAGEis_reference_node (internal/cbm/extract_usages.c) never treats selector_expression as a reference kind; the only occurrence of that node type in the file is a parent check. The reference is the inner field_identifier/identifier, whose own span is bare.

Consequences

  1. The unit test pins a dead branch. ASSERT_FALSE(..., "t.err", "Field") asserts "selector-shaped refs may bind", but Go's extractor cannot produce that input. It is not a production guarantee.
  2. The census that justified the change is a tautology. "100% of Field-targeted USAGE edges carried dot-less reference text, so there is no legitimate population mixed in" is guaranteed by the extractor, not measured from the data. It cannot distinguish noise from signal, which is the job the predicate was given.
  3. Go Field nodes are reference-unreachable. The ~4588 Field nodes recovered by fix(extract): descend into Go struct field_declaration_list #1940 receive no USAGE/READS/WRITES edges at all, including genuine t.err = x writes and cfg.Timeout reads. Only CALLS can reach them.

Not a regression

main had zero Go Field nodes before #1940, so nothing that previously worked is lost. The accurate description of the merged stack is "adds ~4588 nodes that reference edges cannot reach", not "removes edges".

Cheap falsification

Index a Go repository on current main and count Field-targeted USAGE/READS/WRITES edges. The prediction is zero. A non-zero count disproves this issue.

The signal exists but is discarded

The distinction the predicate wants — field_identifier (the field half of a selector) versus identifier (a bare local) — is computed at extraction time and thrown away before the resolver runs. Threading it through would make the guard precise instead of total, and would let genuine x.f references bind while still refusing bare locals.

Suggested resolution

Either thread the field_identifier signal through to the resolver, or keep the blanket veto and make the docstring and unit test say so honestly — the current pair asserts precision the code does not have.

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 edgesstability/performanceServer crashes, OOM, hangs, high CPU/memory

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions