Motivation
#597 turned out to be caused by `parser-native`'s switch_case iteration silently dropping the trailing `return` when a bare case body contained a `[lexical_declaration, if, return]` sequence. Wrapping the case in `{}` fixes it. Other bare multi-statement case bodies may be lurking undetected in the compiler source.
The TypeScript community solved this exact class with the `no-case-declarations` ESLint rule. We should enforce it at the semantic-pass layer so future bugs in this category are compile errors, not silent-wrong native output.
Proposal
New semantic pass in `src/semantic/case-declarations-checker.ts`:
- Walk every `SwitchStatement` in the AST (or every desugared if-ladder that came from a switch).
- For each case's `consequent`, if any statement is a `variable_declaration` / `lexical_declaration` AND the consequent is not a single `BlockStatement` wrapping all of it: emit a compile error pointing at the declaration.
- Fix suggestion in the error: "wrap the case body in braces: `case X: { ... }`".
Wire into `LLVMGenerator.generateParts()` alongside `checkClosureMutations`, `checkUnionTypes`, etc.
Why this is the right fix
Root cause of #597 is deeper in parser-native's tree-sitter handling of bare case bodies — real fix is there, but until that lands, a compile-time rejection is a cheap guard against silent-wrong output. TypeScript itself rejects this pattern in strict mode (`no-case-declarations`), so the constraint is already familiar to users.
Scope
Related: #597 (the bug this prevents future variants of).
Motivation
#597 turned out to be caused by `parser-native`'s switch_case iteration silently dropping the trailing `return` when a bare case body contained a `[lexical_declaration, if, return]` sequence. Wrapping the case in `{}` fixes it. Other bare multi-statement case bodies may be lurking undetected in the compiler source.
The TypeScript community solved this exact class with the `no-case-declarations` ESLint rule. We should enforce it at the semantic-pass layer so future bugs in this category are compile errors, not silent-wrong native output.
Proposal
New semantic pass in `src/semantic/case-declarations-checker.ts`:
Wire into `LLVMGenerator.generateParts()` alongside `checkClosureMutations`, `checkUnionTypes`, etc.
Why this is the right fix
Root cause of #597 is deeper in parser-native's tree-sitter handling of bare case bodies — real fix is there, but until that lands, a compile-time rejection is a cheap guard against silent-wrong output. TypeScript itself rejects this pattern in strict mode (`no-case-declarations`), so the constraint is already familiar to users.
Scope
Related: #597 (the bug this prevents future variants of).