fix(registry): index a symbol under its own name and its QN's tail - #2308
BobbieBarker wants to merge 1 commit into
Conversation
cbm_registry_add takes the symbol's `name` and discards it, deriving the bare-name lookup key from the QN's last dot segment instead. That makes the QN's tail load-bearing for the by-name index every language shares, and it is already wrong for one of them: rust_cfg_qualified_name mints a `#[cfg(test)]` twin as "proj.lib.add#cfg(test)", simple_name() has no '#' handling, so that function is indexed under the literal string "add#cfg(test)" where no bare `add` callee can reach it. The same hole would swallow every arity-fenced Elixir definition the later commits in this stack mint. The caller always knows the name; it is the argument. But the two keys disagree in BOTH directions, so swapping one for the other only moves the hole. A name can equally carry segments the QN's tail drops: grammar def->name QN tail HCL resource.aws_instance.web web TOML tool.poetry.dependencies dependencies INI tool.isort isort Markdown 1.2 Scope 2-Scope Elixir Fx.Store Store all 162 helper.py helper (the file's Module node) The last row is the broad one: a file's Module node is named with the basename including its extension in every grammar, while its QN tail is the extensionless stem a bare module reference is written as. The HCL row is the one with a live reference syntax behind it -- `instance = aws_instance.web.id` reaches the block through the tail `web`, and a name-only key drops that edge outright. So the index carries both keys, and pays for the second only where they differ. No key is removed, so no lookup that resolved before stops resolving. `name` is NULL or empty only for callers that have no symbol name to give; those have the derived key and nothing else. Swept rather than assumed: a throwaway probe walked tests/grammar_cases.h (one fixture per grammar, all 162) comparing def->name with simple_name(def->qualified_name), then targeted fixtures for the dotted shapes above. The Module row appears in all 162; HCL is the only fixture-level mismatch beyond it; TOML, INI, Markdown and Elixir mismatch on the targeted fixtures. XML namespaced elements (`ns:root`) do NOT mismatch: ':' is not a QN separator. tests/test_registry.c: registry_indexes_by_passed_name_not_qn_tail resolves a bare `add` against a cfg-fenced QN. registry_indexes_a_dotted_name_under_its_tail_too resolves an HCL block by its tail and a Module node by its stem. tests/test_pipeline.c: pipeline_hcl_block_reference_resolves_to_its_block indexes a two-resource Terraform file end to end and asserts the surviving USAGE edge. registry_indexes_by_passed_name_not_qn_tail fails without this commit. The other two pass on e783f73 and are here as guards: the by-name index this stack re-keys is what would break them, and an HCL block name is dotted where its QN tail is not, so they pin the shape that regression would take. Opens on #N+4, the branch below it in the delivered chain. It has no content dependency on #N..#N+4: it touches src/pipeline/registry.c plus two test files that none of those commits touch, and it cherry-picks onto e783f73 cleanly. It is ordered before #N+6 because the arity-fenced definitions that commit mints need the passed-name key to stay reachable from a bare callee. Signed-off-by: Chad <4307099+BobbieBarker@users.noreply.github.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
|
Closing in favour of #2310, which carries this commit plus the rest of the set. I split this out first, then realised the pieces cannot land independently: this change creates nodes for guarded functions, which makes a pre-existing phantom self-edge in the calls walk reachable — the regression documented in this PR's own body. It is fixed by a later commit in the set. Merging this alone would ship that regression. Same commit, same tests, unchanged, now in #2310 with the commits it depends on. Sorry for the noise. |
The defect
cbm_registry_addkeys the shared by-name index onsimple_name(qualified_name)— the text after the last dot. For most languages the definition's own name and that tail are the same string, so nothing shows. They are not always the same:find_hcl_block_namereturnsresource.aws_instance.web, and the QN tail isweb#[cfg(...)]twin carries a qualifier in its QN (add#cfg(test)) that its name does notWhichever of the two forms a caller presents, only one of them resolves.
registry_indexes_by_passed_name_not_qn_tailfails onmaintoday for the cfg case.The fix
Index under both the passed
nameand the QN's tail when they differ, so a bare-name lookup resolves either way. The by-name bucket already tolerates several entries per key andreceiver_chain_admitsstill gates every candidate, so this widens what can be found without widening what is accepted.':'is deliberately not treated as a separator: XML namespaced elements (ns:root) do not mismatch.Verification
tests/test_registry.c: registry_indexes_by_passed_name_not_qn_tail— fails onmain, passes with this change.tests/test_registry.c: registry_indexes_a_dotted_name_under_its_tail_tooandtests/test_pipeline.c: pipeline_hcl_block_reference_resolves_to_its_blockpass onmainand are here as guards: they pin the shape a regression in this index would take, which is what the dotted-vs-tail mismatch makes possible.Reported and fixed against
main.