Skip to content

[TS] Preserve lexical constructor and field initializer dispatch - #529

Open
CaelmBleidd wants to merge 3 commits into
mainfrom
caelmbleidd/fix-super-constructor-dispatch
Open

CaelmBleidd wants to merge 3 commits into
mainfrom
caelmbleidd/fix-super-constructor-dispatch

Conversation

@CaelmBleidd

@CaelmBleidd CaelmBleidd commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Direct super(...) calls on symbolic entry receivers could redispatch to the derived constructor and recurse indefinitely. Instance field initialization had the same virtual-dispatch problem: %instInit could run the derived initializer in place of a superclass initializer.

Resolve uncaptured constructor and %instInit calls against their declared owner before receiver-type dispatch. A missing or ambiguous declared target now reaches the existing unknown-call dispatcher once rather than falling through to the derived constructor. Missing owners retain RECEIVER_CLASS_NOT_FOUND, preserving Error/TypeError model and compatibility contracts; a present owner without a unique initializer uses VIRTUAL_METHOD_NOT_FOUND. Captured ordinary .constructor() calls retain their normal callable-property behavior. Dynamic new uses the exact class already selected at its allocation, including union/any inferred results. Allocation provenance is checked across generated argument temporaries and control-flow joins; an unresolved super(this) target still cannot fall back to the child constructor.

Validation:

  • 122 focused tests pass across constructor/runtime-new, Error models and storage, source Error semantics, gap models, compatibility/unknown-call dispatch, PBT preconditions and Kotlin DSL; zero failures or skips.
  • This includes the exact Error/PBT/DSL CI failures caused by the intermediate missing-owner classification, now corrected.
  • RuntimeNewTest (18) and SuperConstructorCall (7) cover dynamic aliases/unions, constructor selection before argument effects, exactly-once calls, and missing-owner superclass dispatch.
  • Adjacent virtual/super behavior was also checked with BuiltinOwnerBoundaryTest (5) and StaticOverloads (7).
  • All four new regression tests fail on the unchanged main baseline, while the three existing constructor tests pass.
  • Explicit three-level and implicit symbolic-receiver constructor results replay in Node (71 and 13), including initializer ordering. Tests use ordinary TypeScript sources; no registers or heap are manually prepared.
  • :usvm-ts:detektMain, :usvm-ts:detektTest, and git diff --check pass.

The missing-owner regression uses an ambient superclass declaration excluded from the executable scene. This covers the unresolved-owner dispatch mechanism; it does not add support for native Error subclassing, which the current frontend already rejects explicitly. A separate existing defect with shadowed inherited field declarations was discovered and retained as a failing reproduction, outside this dispatch fix.

No JacoDB dependency change is required. Full module suites and the 200-class campaign are left to CI and the combined integration run.

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.

1 participant