Repository navigation
A derived class's implicit constructor passes its arguments to the base - #557
Merged
Merged
Conversation
TypeScript gives a derived class with no constructor an implicit
`constructor(...args) { super(...args); }`. tslang generated one only
for a class with field initializers, and as `constructor() { super(); }`,
so `new Derived(2, 3)` failed with "Expected 1-2 arguments, but got 0"
when the base constructor takes parameters. The generated constructor
now takes the base constructor's parameters, typed as its function is
(a generic base's already specialized; optional and rest parameters
included), and passes them to `super`; the base applies its defaults.
That needed `super(a, ...rest)` to work: a super call's arguments were
generated without the constructor's parameters (the callee is the base
class), so a spread had no count to fill and the base got an empty rest
parameter. They are generated against the base constructor now.
Errors in the generated constructor and in the assignments generated
for field initializers were reported at 1:1, as those nodes had no
position. They are reported at the class and at the field now:
`argv: Ref<string> = null` says 6:5, not 1:1.
Found while porting native_ts_graphics samples (TSLANG_ISSUES.md 1, 2
and the location in 4).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ASDAlexander77
added a commit
that referenced
this pull request
Oct 17, 2026
…de for (#581) A node the compiler builds (a for...of's or for...in's loop, the call of `[Symbol.iterator]`, a `using`'s dispose call) has no position, so an error in it was reported at 1:1: for (const x of 5) {} // 1:1: Can't resolve property 'length' of type s32 using x = 5; // 1:1: Can't resolve property 'dispose' of type s32 Each statement now records where it is (without the debug scope), and loc() gives a node with no position that location, in the current scope; a statement the compiler made keeps the anchor of the one it was made for. The dispose call, made at the scope's exit, is anchored at its declaration. #541 and #557 had stamped positions on the generated cast and constructor nodes one at a time; this covers the rest. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TypeScript gives a derived class with no constructor an implicit
constructor(...args) { super(...args); }. tslang generated one only when the class had field initializers, and asconstructor() { super(); }:mlirGenClassDefaultConstructor): it takes the base constructor's parameters, typed from its function type, so a generic base is already specialized. Optional and rest parameters are included. It passes them tosuper, and the base applies its own defaults. The parameters are named.argN, so a field initializer, which runs in this constructor, still sees an outer variable of the same name.super(a, ...rest)passed an empty rest parameter. The callee of a super call is the base class, so its arguments were generated with no parameter list, and a spread had no count to fill. They are now generated against the base constructor's function type.protected argv: Ref<string> = null;now reports at 6:5.Tests:
00class_implicit_constructor.ts(compile + JIT, and the rc/none corpus) covers defaults, optional and rest parameters, a two-level chain, generic and specialized bases, and the shadowing case. Twodiagnostic-locationtests check the error positions. I also checked by hand a base imported from another module, with and without the JIT cache. Full suite: 4020/4020 passed (Release).Found while porting native_ts_graphics samples (issues 1 and 2 of the native_ts_graphics findings; the location part of issue 4). With this, the forwarding constructors added in native_ts_graphics PR #48 can be deleted.
🤖 Generated with Claude Code