Skip to content

[TypeScript] Same-name overload signatures collapse to one — detector.py drops 6 of 7 bodyless pipeable overloads #2278

Closed

Description

@squid-protocol

Follow-up/continuation of #2219 — the ledger shape typescript/function/existence/agree[ctags,tree_sitter]_vs[gitgalaxy] (7 occurrences) is still still_reproduces: true after re-reconciling today, even though #2219's regex fix (widening the arrow-function branch's generics tolerance) is confirmed landed and working for the standalone-function case. Root-caused precisely this time, and it's a different bug from #2219 despite sharing a symptom.

Real example, fp-ts/pipeable.ts:2344-2520 — 7 consecutive TypeScript function-overload signatures, 6 bodyless (terminated by the next /** @deprecated */ / next overload, no {), 1 with a real body:

export function pipeable<F extends URIS3, I>(
  I: { readonly URI: F } & I
): (I extends Chain3<F>
  ? PipeableChain3<F>
  ...
  : {}) &
  (I extends Contravariant3<F> ? PipeableContravariant3<F> : {}) &
  ...
/** @deprecated */
export function pipeable<F extends URIS3, I, E>(
  ...
// ... 5 more overloads, same shape ...

export function pipeable<F, I>(I: { readonly URI: F } & I): Record<string, unknown> {
  const r: any = {}
  if (isFunctor<F>(I)) {
  ...
}

tree-sitter and ctags both correctly report all 7 as distinct pipeable occurrences (confirmed via the ledger's own last_seen_examples, lines 2344/2374/2404/2433/2463/2490/2520 — all present in both other tools' readings).

Confirmed NOT a regex miss — tested LANGUAGE_DEFINITIONS["typescript"]["rules"]["func_start"] directly against the isolated overload text: it matches pipeable fine, including the multi-line generic-bound signature. This is the same regex #2219 already fixed for the single-signature case.

Confirmed a detector.py body-slicing/dedup bug, via galaxyscope --db-only against fp-ts/pipeable.ts (step 2b of this repo's tri-comparison-ledger-sweep skill):

SELECT struct_func_start, function_count FROM file_data WHERE file_path LIKE '%pipeable.ts%';
-- struct_func_start=224  function_count=217   (raw regex signal vs. named list: off by exactly 7)

SELECT func_name, start_line FROM function_data WHERE func_name = 'pipeable';
-- only ONE row: (pipeable, 2520)  -- the sole body-bearing overload

The raw signal count (computed independently of body-slicing) sees all 7 pipeable matches; the named list that actually reaches function_data (and therefore every downstream consumer — LLM briefs, SARIF, risk scoring) keeps only the one WITH a real {...} body, at line 2520. The 6 bodyless overload signatures are silently swallowed somewhere in detector.py's per-function slicing/naming path — most likely a same-name dedup or a brace-matching step that treats the bodyless overloads as incomplete/orphaned matches and drops them rather than emitting a signature-only occurrence for each.

Suspected mechanism (not yet pinned to an exact line): each bodyless overload's return-type annotation contains literal {} (empty-object-type intersection members, e.g. : {}) &) — if _slice_by_braces treats the first { after a func_start match as the body opener regardless of whether it's really a block vs. a type-level brace, it would misattribute/consume the wrong span and could plausibly explain the collapse, but this needs a real detector.py trace to confirm rather than staying a guess.

Confirmed scope: exactly 7 occurrences, all in this one file/shape (multi-overload same-name function declarations with a type-heavy bodyless signature) — the ledger's own capped example list already has the complete set (7 ≤ the 10-example cap), so this is unlikely to be under-counted.

Why not fixed inline: root cause is inside detector.py's shared slicing/naming path, not an isolated per-language regex — needs an actual trace through that code before a safe fix, and any fix there risks rippling into every Mode B language's overload/bodyless-declaration handling, not just TypeScript. Filing per this repo's scope discipline (diagnose precisely, fix separately) rather than shipping an unverified change to shared slicing logic.

Activity

  1. added
    bugUnintended behavior or logic failure in the engine
    core-engineModifications to the central physics and parsing engine
    threat: false-negativeAccuracy tuning: Engine missed a bypass or vulnerability
    on Aug 26, 2026
  2. squid-protocol commented on Aug 26, 2026

    @squid-protocol
    OwnerAuthor

    Second confirmed instance of the same mechanism, found continuing the same sweep: vscode/instantiationService.ts:116-118 —

    createInstance<T>(descriptor: SyncDescriptor0<T>): T;
    createInstance<Ctor extends new (...args: any[]) => unknown, R extends InstanceType<Ctor>>(ctor: Ctor, ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>>): R;
    createInstance(ctorOrDescriptor: any | SyncDescriptor<any>, ...rest: unknown[]): unknown {
        this._throwIfDisposed();
        ...
    }

    Same shape as pipeable: 2 bodyless overload signatures + 1 body-bearing implementation, same name. GitGalaxy's function_data keeps only the implementation, matching the struct_func_start vs. function_count split already confirmed for pipeable. Also confirms this isn't specific to files with only bodyless overloads (like fp-ts/pipeable.ts) — it recurs in an ordinary implementation file too, wherever a real function has TS overload signatures declared above it. Raises confidence this is a systemic detector.py mechanism, not a corpus-specific quirk. Also found 2 same-named constructor occurrences and 1 cancel() dropped in vscode/async.ts (lines 2526-2537, CancelableAsyncIterableProducer class) that look like the same collapse mechanism triggered by multiple classes sharing the name `constructor" in one file, though not root-caused as precisely as the overload case above.

  3. added this to the v2.4.9 milestone on Aug 31, 2026
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

    bugUnintended behavior or logic failure in the enginecore-engineModifications to the central physics and parsing enginepriority: mediumthreat: false-negativeAccuracy tuning: Engine missed a bypass or vulnerability

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions