You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Examples/wip.das documents three latent footguns in the class system. This
PR closes two of them and removes the dormant opt-in lint that was supposed
to cover the third.
(1) Every derived-class constructor whose parent has a user-defined ctor
must call super(...) exactly once on every control-flow path. Replaces the
opt-in always_call_super single-bool check with a CFG-aware {lo, hi}
walker (countSuperCalls) modeled on exprReturns. Catches missing super,
super on only one if/else branch, super in a loop (unbounded count),
super called twice on the same path. Handles try/recover: the try block
is the normal-flow path; the recover block is fatal-panic-with-diagnostics
and is ignored (matched on both the direct ExprTryCatch and the JIT-mode
builtin_try_recover rewrite via call->func->module->name == "$" guard).
(2) super(...) and super.X() may only walk past an intermediate class that
has no user-defined ctor or matching method. Skipping a class with its
own user ctor (whose invariants would silently be bypassed) is rejected
at the typer with invalid_super_call. Empty-intermediate skip (e.g. the
SkipMid pattern in tests/language/super.das) stays legal.
The always_call_super option is hard-removed - policy field, lint binding,
option-table row, serialize stream byte, and doc references all deleted.
Out of scope (PR2): synthesizing a derived default ctor that chains via
super() when no user ctor is provided.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments