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
Keep a case's guard as data until its fallthrough is known
Matching encoded a guard as a term and recovered it afterwards by shape:
translcore emitted [if cond then body else Lstaticraise (0, [])], and
is_guarded / patch_guarded recognised that shape to substitute the real
fallthrough. Exit zero was a sentinel, not an exit.
Normalization cannot know a shape is a message. Fold the condition of
[x if 1 > 2] and if_ correctly returns the else branch, so the action becomes
a bare raise to an exit that has no catch, is_guarded stops recognising it,
nothing patches it, and the raise reaches codegen alone. That is what broke
the analysis corpus when mk_builtin started folding.
Carry the guard as data instead. A case's right-hand side is now
type action = {
binds: (let_kind * Ident.t * Lambda.t) list;
guard: Lambda.t option;
body: Lambda.t;
}
lowered at the single point where the fallthrough exists - the row that
matches in compile_match. The bindings are there because simplification
brings pattern variables into scope with lets that must cover the guard as
well as the body; keeping them as data preserves that without a term to
recurse through. staticfail, is_guarded and patch_guarded are deleted, and
exit zero is no longer magic.
Comparing actions needs a stand-in for the fallthrough, and it must be a
fresh variable rather than a constant: with unit, [when g => e] and
[_ => if g then e else ()] produce the same key, and merging them loses one
evaluation of g. The variable is created per comparison, so its freshness
does not depend on ident stamps surviving Ident.reinit between units.
guard_action_test pins both: a guard that folds to false is not a missing
guard, and two actions that differ only in where the condition sits are not
the same action. Each fails on the unfixed compiler.
Generated JavaScript is unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W8g8qwBARAcvW9MyuKQq8H
0 commit comments