Skip to content

Overload signatures are types only; the implementation is the function - #378

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fix-overload-signatures
Sep 27, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
fix-overload-signatures

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Fixes #343. Overload signatures crashed the compiler, with or without a call:

function f(a: number): number;
function f(a: number, b: number): number;
function f(a: number, b?: number) { return b === undefined ? a : a + b; }

Cause

A body-less function was registered as a function. mlirGenFunctionSignaturePrototype looks for an already-discovered function by its bare name. When it finds one, it reuses that function's type in place of the parameter list it has just built. So the implementation f(a, b?) took the one-parameter type of the first signature. Its entry block got one argument for two parameters, and mlirGenFunctionParams read arguments[1] past the end.

That is why "remove either signature and it compiles" was only half true: keeping only the one-parameter signature still crashes. With the longer signature first, the result is "redefinition of symbol" instead of a crash.

Fix

  • Functions: outside an ambient context, a function without a body is only legal in TypeScript as an overload signature, so mlirGen(FunctionDeclaration) now skips it. The implementation is the one function, and calls are checked against its parameter list. The overload signatures themselves are not checked against the calls.
  • Methods and constructors: their overload signatures crashed the same way (c.m(1) with m(a), m(a, b), m(a, b?) {…}). mlirGenClassMethodMember skips them too.
  • Unchanged:
    • ambient declarations: declare function, anything in a .d.ts (including the __decls text of -shared modules, which is parsed as one), imported classes, and declaration-only class expressions;
    • abstract methods.
  • Changed behaviour: a body-less function with no implementation after it, and no declare, used to be treated as an external symbol. It now fails with can't resolve name at the call. TypeScript rejects that code too, with TS2391 "Function implementation is missing". Nothing in this repo or in TypeScriptCompilerDefaultLib relies on it: every external declaration there uses declare or a .d.ts.

Tests

  • New 00function_overloads.ts (compile, jit, and the rc/none corpus). It covers:
    • overloads, including ones that are never called;
    • a union-parameter implementation;
    • overloads in a namespace and inside a function body;
    • constructor, method and static method overloads;
    • an overloaded override of an abstract method.
  • Full release suite: 2968/2968 passed.

Not in this PR

declare function overloads, and a .d.ts with several signatures of one name, still report "redefinition of symbol". That is an error, not a crash. Supporting them needs real overload resolution, since each signature would be a separate external.

🤖 Generated with Claude Code

A body-less function outside an ambient context is an overload signature, but
it was registered as a function. The next declaration of the same name, the
implementation, then took the cached signature's parameter list, so its body
indexed past the entry block's arguments: an ArrayRef assert in debug and an
access violation in release, with or without a call (#343).

Function overload signatures are now skipped, and so are method and
constructor overload signatures in a class, which crashed the same way. Ambient
declarations (`declare`, a .d.ts, imported classes, declaration-only class
expressions) and abstract methods keep their meaning.

Fixes #343

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit f9ee3cf into main Sep 27, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix-overload-signatures branch September 27, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Overload signatures crash the compiler (assertion in ArrayRef), with or without a call

1 participant