Skip to content

Aiur: support non-tail match on a non-variable scrutinee#435

Merged
arthurpaulino merged 1 commit into
mainfrom
ap/non-tail-match
Jun 4, 2026
Merged

Aiur: support non-tail match on a non-variable scrutinee#435
arthurpaulino merged 1 commit into
mainfrom
ap/non-tail-match

Conversation

@arthurpaulino
Copy link
Copy Markdown
Member

The match compiler hoists a non-variable match scrutinee into a fresh let (MatchCompiler.switch), so let x = match foo(bar) {..} simplified to let x = (let w = foo(bar); match w {..}). That buried the match one let deep, where Lower's non-tail-match detector — which only fires when a match is the immediate letVar/letWild RHS — couldn't see it, and lowering threw "Non-tail match in arbitrary position (not supported)".

Fix in the Simple stage: mkLetFloating floats leading lets out of a let-RHS (let x = (let w = e; rest); b -> let w = e; let x = rest; b), restoring the invariant that a non-tail match sits directly in its letVar/letWild RHS. The hoisted w's are fresh match-compiler locals, so widening their scope cannot capture anything.

Tests: ntm_match_on_call exercises a function-call scrutinee, folded into the non_tail_match aggregate in both the aiur and aiur-cross suites.

The match compiler hoists a non-variable match scrutinee into a fresh
let (MatchCompiler.switch), so `let x = match foo(bar) {..}` simplified
to `let x = (let w = foo(bar); match w {..})`. That buried the match one
let deep, where Lower's non-tail-match detector — which only fires when a
match is the immediate letVar/letWild RHS — couldn't see it, and lowering
threw "Non-tail match in arbitrary position (not supported)".

Fix in the Simple stage: mkLetFloating floats leading lets out of a
let-RHS (`let x = (let w = e; rest); b` -> `let w = e; let x = rest; b`),
restoring the invariant that a non-tail match sits directly in its
letVar/letWild RHS. The hoisted w's are fresh match-compiler locals, so
widening their scope cannot capture anything.

Tests: ntm_match_on_call exercises a function-call scrutinee, folded into
the non_tail_match aggregate in both the aiur and aiur-cross suites.
@arthurpaulino arthurpaulino enabled auto-merge (squash) June 4, 2026 16:04
@arthurpaulino arthurpaulino merged commit e2794c9 into main Jun 4, 2026
14 checks passed
@arthurpaulino arthurpaulino deleted the ap/non-tail-match branch June 4, 2026 16:07
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