Skip to content

fix(swift): preserve declaration identity and compatible call edges - #2436

Open
DavidHLP wants to merge 53 commits into
DeusData:mainfrom
DavidHLP:feat/issue-2061-swift-identity
Open

DavidHLP wants to merge 53 commits into
DeusData:mainfrom
DavidHLP:feat/issue-2061-swift-identity

Conversation

@DavidHLP

@DavidHLP DavidHLP commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes Swift overloads sharing a graph node and inheriting each other's calls in #2061. This builds on the merged #2342 plumbing and enables Swift only.

Declaration identities retain parameter labels and types, generics and constraints, where requirements, async, qualified type paths and explicit return types. Node names stay bare. Call resolution uses labels, arity, defaults and trailing closures, and keeps every compatible candidate when it cannot choose one. It does not infer types or resolve aliases.

Qualified types are written as A/Item; explicit returns as pick()=>Int or pick()async=>String. Format4 rebuilds older indexes once to replace collided nodes and stale calls. I'd appreciate a review of that format boundary before merging.

Head: 6ca78d06e66a8d60c12c72618cbd9fd6cf9f8e21, merging main e71f23ecf40e473a3e0a49cff1ffebcccead384d without rewriting published history. Six conflicts were resolved by retaining Swift signature/default metadata alongside upstream definition test metadata, language-aware registration and SPAWNS handling. Incremental registry seeding restores both language and Swift metadata; unresolved parallel route calls retain upstream self-loop suppression. GitHub now reports this head mergeable.

At this merge head on local Linux/GCC 16.2.1, conflict-file syntax checks, whole-tree formatting, NOLINT and memory-core checks passed. The five-suite ASan/UBSan build was stopped after a prolonged first build in generated LSP standard-library data; no suite result is claimed. The full test entry stopped at a sandbox-denied fixture-server bind. CI lint cannot run locally without cppcheck, and full clang-tidy reports errors. Current-head DCO passed on GitHub; remaining upstream checks and maintainer approval are pending.

The runtime evidence below is historical: tested code 10f4769779c8ec63d509b7884219187a0e7a1939, documented at 35533b2674a09e2e6e9a066faf52e3fb8ccdaada. It has not been rerun at the merge head.

The new tests fail on the old implementation with one node instead of two for both qualified-parameter and return-only overloads. They pass after the fix and check source locations, outgoing calls, candidate counts, serial/parallel indexing, persistence and migration. Existing default-argument, closure, ownership and boundary regressions are retained. The standalone graph/MCP drivers are opt-in.

On remote-dev (Linux x86_64, GCC16.2.1), 909 focused tests and 328 pipeline TSan tests passed. Strict graph10/10 and real MCP5/5, the clean production build and CI lint also passed. CI lint needed a retry with a longer time limit; the timeout log is retained. All49 commits pass DCO.

There are still two ObjectScript UBSan reports, so the focused run is not sanitizer-clean; their cause is unconfirmed. The full C entry stops at the Scoop metadata precheck, full clang-tidy is not passing, and native CLI version/help exit139 with the same startup stack as the earlier main comparison. Current macOS/Windows/Ubuntu CLI semantics have not been checked. Upstream checks and maintainer approval are pending.

Review summary · Commands and raw logs · Validation notes.

Written with Codex on behalf of DavidHLP.

Checklist

  • Every commit is signed off (git commit -s) — all49 checked.
  • Tests pass locally (make -f Makefile.cbm test) — focused remote runs pass; the full run and sanitizer limitations are noted above.
  • Lint passes (make -f Makefile.cbm lint-ci) — historical CI lint passed; current-head upstream lint pending and local cppcheck unavailable.
  • New behavior is covered by a test (reproduce-first for bug fixes).

DeusData and others added 8 commits September 25, 2026 18:49
…Data#2061)

Overloads that share a base QN (Java/C#/C++/Kotlin/Swift/Scala/ObjC) merge
into one graph node today, and that node collects the CALLS of every
overload. The agreed cure is one signature-qualified callable identity for
all overloading languages:

    callable_qn := base_qn [<tparams>] (params) [cvref]

This change lands the plumbing with every language still at
CBM_CALLABLE_ID_NONE, so the graph is byte-identical; each language is
switched on later in its own change (with its index-format bump).

- internal/cbm/callable_sig.{c,h}: the per-language mode side table
  (NONE|TYPED|LABELED_TYPED|LABELED|ARITY; kept out of CBMLangSpec like
  cbm_string_dispatch_suffixes, since ~160 positional rows would otherwise
  all need the member under -Wmissing-field-initializers), the shared
  builder cbm_callable_sig[_mode] for the def and the call-scope QN, and
  the inverse cbm_qn_callable_base_len[_named]. Suffix contract: no '.',
  '::' or '->'; whitespace-normalized; comments/annotations/attributes
  dropped; qualified types keep their last segment; '->' spelled '=>';
  variadic '[]' (Java) / '~'; C++ top-level cv dropped, arrays decay,
  cvref kept; <= 200 bytes, longer ones keep whole leading entries and end
  in '#<fnv1a64 of the full suffix>)'. The builder is iterative (cursor
  walk, bounded declarator loop) and self-checks against the inverse.
- The inverse is anchored to the node's bare name wherever the name is
  known: real QNs already end in ')' without being callables (a Java field
  whose name is its declarator `X = f()`, make `$(VAR)` targets), and only
  the anchor makes the inverse exact on them.
- Leaf splitters strip a suffix first (no-op today): registry by-name key
  (indexed by the bare name for a suffixed callable), cbm_lsp_bare_segment,
  cbm_pipeline_qn_class_method_tail, pxc_last_component, pxc_qn_leaf,
  go_index_visit_node, collect_prod_defs, sg_qn_prefix_len.
- New unused fields: CBMDefinition.qn_sig_off, CBMResolvedCall.callee_sig
  (relocated by result compaction), CBMRegisteredFunc.sig, CBMLSPDef.sig.
  The lsp_surface codec is unchanged (no format bump in this change).
- get_code_snippet and trace_path gain base-QN tiers
  (cbm_store_find_nodes_by_qn_base) that find nothing until suffixes exist.
- store: cbm_store_find_nodes_by_qn_suffix built its LIKE pattern in a
  512-byte buffer (a long suffix was truncated into a pattern that matched
  nothing) and did not escape '_'/'%' (`my_func` also matched `myXfunc`).
  The pattern is now heap-built, escaped, and matched with ESCAPE '\'.

Proof: full sorted node+edge+lsp_surface dumps are byte-identical before
and after on 7 corpora (this repo, elasticsearch libs, Exposed, dotnet
System.Linq, System.Collections, coreclr/gc, a C corpus).

Refs DeusData#2061

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Enable typed, labeled Swift callable identities on the shared DeusData#2061 plumbing. Resolve calls by compatible labels, defaulted parameters, and trailing closures; retain all compatible overload edges with candidate counts. Cover registry, pipeline, and signature behavior.

Refs DeusData#2061

Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Force the parallel call pass on a Swift fixture and assert both label-compatible type overloads retain CALLS edges with the ambiguity count.

Refs DeusData#2061

Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
A Swift call that shares its bare name with project symbols but matches
none of their overloads was handled differently by the two resolvers:
the parallel path cleared the bare-name match and fell through as
unresolved (keeping each resolver's empty-resolution service
fallbacks), while the sequential path dropped the call outright. Skip
the bare-name registry bind on the sequential path too — it would bind
a wrong overload — and continue as unresolved, so count < 0 behaves
exactly like any other unresolved call on each resolver.

Pipeline regressions pin the global-fetch fallback (DeusData#856) on both
paths: the incompatible local overload gets no wrong CALLS edge, and
the URL call keeps its HTTP_CALLS edge. The route-registration fallback
differs between the paths on main (sequential additionally requires a
'/'-leading first argument); that pre-existing divergence is out of
scope here.

Refs DeusData#2061

Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
@github-actions

Copy link
Copy Markdown

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. 0.9.1-rc.1 is out, so the release freeze that held reviews is over — but it left a large queue of open pull requests behind it, and we are reading through them oldest-first. The background is in discussion #1144.

What that means for this PR, concretely:

  • It will not be closed for inactivity. No stale bot touches pull requests here.
  • It may still sit a while before a human reads it. That is on us, not on you.
  • Older PRs are read first, so a recent one is not being skipped — it is behind a queue.

Things that will genuinely speed it up whenever review does happen:

  • Keep it rebased on main — the tree is moving quickly right now, and a conflicting branch cannot be reviewed as the diff you intended.
  • Get CI green, or say which failures you believe are pre-existing.
  • Keep the change to one claim. Bundled features and refactors get split before they get merged, which costs you a round trip.
  • Every commit needs a sign-off (git commit -s) — CI enforces DCO.

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.

Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
@DeusData
DeusData force-pushed the feat/callable-identity-plumbing branch 2 times, most recently from 3441da4 to 5538355 Compare September 30, 2026 22:34
Signed-off-by: DavidHLP <lysf15520112973@163.com>
@DeusData DeusData added enhancement New feature or request parsing/quality Graph extraction bugs, false positives, missing edges priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Oct 1, 2026
@DeusData

DeusData commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Thank you for the detailed status update and for clearly distinguishing the actual PR head from unpublished work and unverified results. The changed-file scope includes callable identity, resolution and persisted metadata, so we need more time for a complete review together with the parent change. This remains queued for deeper review; this comment is not an approval or a request for another routine rebase. The queue is full, and we appreciate your patience and the care taken to document the remaining work.

Swift-scope checkpoint for DeusData#2061: capture bounded trailing-closure labels, match Swift overload candidates conservatively, and cover extraction, registry, compact/spill, serial, parallel, and incremental behavior.

Validation: ASan passed on the combined WIP source only; this A-only checkpoint has not been independently verified. GCC TSan, smoke, and memory gates remain failed/open. This commit is a scope checkpoint, not acceptance.

Signed-off-by: David HLP <lysf15520112973@163.com>
Signed-off-by: David HLP <lysf15520112973@163.com>
Signed-off-by: David HLP <lysf15520112973@163.com>
Signed-off-by: David HLP <lysf15520112973@163.com>
Signed-off-by: David HLP <lysf15520112973@163.com>
Signed-off-by: David HLP <lysf15520112973@163.com>
Signed-off-by: David HLP <lysf15520112973@163.com>
@DavidHLP
DavidHLP force-pushed the feat/issue-2061-swift-identity branch from 4dbfd27 to eea3143 Compare October 3, 2026 09:49
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
…onditions

Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
@DavidHLP
DavidHLP marked this pull request as ready for review October 5, 2026 07:29
@DavidHLP
DavidHLP marked this pull request as draft October 5, 2026 08:08
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>
@DavidHLP DavidHLP changed the title fix(swift): preserve overload identity and compatible call edges fix(swift): preserve declaration identity and compatible call edges Oct 5, 2026
@DavidHLP
DavidHLP marked this pull request as ready for review October 5, 2026 09:35
@DavidHLP

DavidHLP commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor Author

I've finished the Swift fixes on top of #2342. The current head is 35533b2674a09e2e6e9a066faf52e3fb8ccdaada; the code was tested at 10f47697, and the last commit only updates the validation notes.

The two remaining collisions now have separate identities: A.Item versus B.Item, and functions that differ only in their declared return type. The tests reproduce each collision before the fix, then check separate nodes, source locations and outgoing calls, including parallel indexing and reopening the index. Call resolution still keeps all compatible candidates rather than guessing from types.

The main thing I'd like feedback on is the identity spelling: qualified types use /, explicit returns use =>Type, and format4 rebuilds older indexes once. The implementation and migration tests are in callable_sig.c, registry.c and test_index_format.c.

On remote-dev, 909 focused tests and 328 pipeline TSan tests passed, along with the separate graph and MCP checks, production build and CI lint. There are still two ObjectScript UBSan reports, so the focused run isn't sanitizer-clean. The full C run stops at the Scoop metadata precheck, full clang-tidy still reports errors, and the native CLI crashes at startup with the same stack seen in the earlier main comparison. Current macOS, Windows and Ubuntu CLI checks haven't been run.

Test commands and full logs are available here. I removed the duplicate progress comments; their original text is archived. This is ready for review, with the remaining checks and approval still pending.

Signed-off-by: DavidHLP <lysf15520112973@163.com>
Signed-off-by: DavidHLP <lysf15520112973@163.com>

This branch has not been deployed

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

Labels

enhancement New feature or request parsing/quality Graph extraction bugs, false positives, missing edges priority/normal Standard review queue; useful PR with ordinary maintainer urgency.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants