Iter 16d: chain-terminator via __unreachable__ builtin
Eliminates the Unit-typed chain default that 16c left in place.
Adds __unreachable__ : forall a. a — codegen lowers to LLVM
unreachable. The 16a/16c chain machinery now uses it as the
deepest fall-through, so exhaustive matches with non-Unit arms
no longer need a (case _ ...) workaround.
- check/builtins.rs: register __unreachable__ as Forall(a, a).
- codegen: Term::Var "__unreachable__" emits LLVM unreachable
and sets block_terminated; If/Match/fn-body gate downstream
work on that flag.
- desugar: chain default switched from Lit{Unit} to Var.
- examples/lit_pat: categorize_first's trailing _ arm removed.
Hash changes from c4faec3abc2ed388 to 644de0c0ec15fc17.
- examples/unreachable_demo: positive fixture using safe_div
with __unreachable__ in the impossible branch.
- e2e + desugar tests: 122 → 124 (+2).
Path-a from 16b.2 planning: real primitive over a desugar-time
exhaustiveness pre-check (which would need cross-module type
registry access from desugar).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1109,9 +1109,31 @@ fn check_json_unbound_var() {
|
||||
/// either a wrong result or an `unreachable!` panic depending on
|
||||
/// the path. The fixture exercises both sites: `classify` (top-
|
||||
/// level lit arms) and `categorize_first` (nested lit-in-Ctor).
|
||||
///
|
||||
/// Iter 16d update: the trailing `(case _ 0)` arm of
|
||||
/// `categorize_first` was removed when the chain machinery's
|
||||
/// terminator switched from a `Unit` literal to the polymorphic
|
||||
/// `__unreachable__` builtin. Output is unchanged — this test
|
||||
/// guards both 16c (lit-pattern desugar) and 16d (no-workaround
|
||||
/// chain default).
|
||||
#[test]
|
||||
fn lit_pat_demo() {
|
||||
let stdout = build_and_run("lit_pat.ail.json");
|
||||
let lines: Vec<&str> = stdout.lines().collect();
|
||||
assert_eq!(lines, vec!["100", "200", "999", "-1", "0", "7"]);
|
||||
}
|
||||
|
||||
/// Iter 16d: `__unreachable__` as an explicit user-callable
|
||||
/// primitive. Property protected: a polymorphic `forall a. a` value
|
||||
/// reference (a) typechecks against any expected type at the use
|
||||
/// site (here `Int`), and (b) codegen lowers it to LLVM
|
||||
/// `unreachable`, with the surrounding `if` correctly forwarding
|
||||
/// the live branch's value past the terminated branch. The fixture
|
||||
/// only ever hits the live branch, so the binary must succeed and
|
||||
/// print the expected outputs.
|
||||
#[test]
|
||||
fn unreachable_demo() {
|
||||
let stdout = build_and_run("unreachable_demo.ail.json");
|
||||
let lines: Vec<&str> = stdout.lines().collect();
|
||||
assert_eq!(lines, vec!["4", "5"]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user