The verdict table's reject half is enforced: a Haxe habit fails loudly at
its own position with the doctrine reason, instead of a generic syntax
error — or, worst, compiling clean: `return super.f()` used to exit 0 (the
unresolved ident placeholder swallowed it).
- parser.ml: doctrine_reject_reason maps each rejected word to its spec
reason (inheritance quartet -> principle 4; cast; Dynamic/untyped ->
principle 13; macro; extern -> principle 10; operator). Fired at three
chokepoints: `class B extends A` (with skip-to-brace recovery so the body
still parses), an expression head (`super`, `cast 3`, `untyped x`), and a
top-level declaration head (`macro fn`, `extern fn`).
- types.ml: `Dynamic`/`untyped` as a TYPE name keep their WO-E225 site but
carry the doctrine message.
- corpus: compile-fail/{reject-inheritance,reject-cast,reject-dynamic}.
- catalog WO-E105 row; plan 8 Task 8 reject half ticked (#if still open);
board updated.
Verified: woc-test 540/0 + test_diag 14/0; oop-e2e 86/0; log-watcher 7/0;
employee 8/0; legit identifiers (`extended`) untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
14 lines
297 B
Text
14 lines
297 B
Text
-- Doctrine reject (WO-E105): no inheritance, ever. `extends` fails at its
|
|
-- own position with the doctrine reason (principle 4), never a generic
|
|
-- syntax error. `super`/`override`/`implements` share the row.
|
|
class A {
|
|
n: Int
|
|
}
|
|
|
|
class B extends A {
|
|
m: Int
|
|
}
|
|
|
|
fn main() -> Int {
|
|
return 0
|
|
}
|