Skip to content

Fix match-pattern miscompile from stale unboxable marks#525

Open
nbeerbower wants to merge 2 commits into
mainfrom
claude/fix-bugs-from-merges-X5q2J
Open

Fix match-pattern miscompile from stale unboxable marks#525
nbeerbower wants to merge 2 commits into
mainfrom
claude/fix-bugs-from-merges-X5q2J

Conversation

@nbeerbower

Copy link
Copy Markdown
Collaborator

Same bug pattern as PRs #519 and #522: a prior same-named binding
(e.g. for (let i = 0; ...) counter, or an inferred let i = 0)
marks the name as unboxable in the type-check context. The match
pattern binding sites in codegen_expr_match.c emit a boxed HmlValue
declaration but never clear that mark, so codegen_expr_ident treats
subsequent references as a native C primitive and emits
hml_val_i32(x) on an HmlValue — producing a C compile error, or, if
the prior native type happens to match, silent miscompilation.

Clear the unboxable mark at every pattern binding site:

  • PATTERN_BINDING (x => ...)
  • PATTERN_TYPED (x: i32 => ...)
  • PATTERN_OBJECT shorthand ({ x, y } => ...)
  • PATTERN_OBJECT rest ({ x, ...rest } => ...)
  • PATTERN_ARRAY rest ([a, b, ...tail] => ...)

This mirrors the existing treatment in let, for counter, and
for-in codegen paths.

Added tests/parity/language/match_stale_unbox covering all five
binding sites.

claude added 2 commits April 18, 2026 00:51
Same bug pattern as PRs #519 and #522: a prior same-named binding
(e.g. `for (let i = 0; ...)` counter, or an inferred `let i = 0`)
marks the name as unboxable in the type-check context. The match
pattern binding sites in codegen_expr_match.c emit a boxed `HmlValue`
declaration but never clear that mark, so codegen_expr_ident treats
subsequent references as a native C primitive and emits
`hml_val_i32(x)` on an HmlValue — producing a C compile error, or, if
the prior native type happens to match, silent miscompilation.

Clear the unboxable mark at every pattern binding site:
  * PATTERN_BINDING         (`x => ...`)
  * PATTERN_TYPED           (`x: i32 => ...`)
  * PATTERN_OBJECT shorthand (`{ x, y } => ...`)
  * PATTERN_OBJECT rest     (`{ x, ...rest } => ...`)
  * PATTERN_ARRAY rest      (`[a, b, ...tail] => ...`)

This mirrors the existing treatment in `let`, `for` counter, and
for-in codegen paths.

Added tests/parity/language/match_stale_unbox covering all five
binding sites.
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.

2 participants