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:
2026-05-07 23:00:23 +02:00
parent e5f9828a04
commit af35612c1d
10 changed files with 353 additions and 14 deletions
+13
View File
@@ -798,6 +798,19 @@ What **is** supported (and used as the smoke test for the pipeline):
- `if`, `let`, function calls, recursion.
- Effects on function signatures, with `do op(args)` for direct effect
ops (`io/print_int`, `io/print_bool`, `io/print_str`).
- **Builtins.** Arithmetic and comparison operators (`+`, `-`, `*`,
`/`, `%`, `==`, `!=`, `<`, `<=`, `>`, `>=`) of type
`(Int, Int) -> Int` / `Bool`; logical `not : (Bool) -> Bool`; the
IO effect ops listed above; and **`__unreachable__ : forall a. a`**
(Iter 16d). The latter is a polymorphic bottom value: a use of
`__unreachable__` typechecks against any expected type at the use
site and codegens to the LLVM `unreachable` instruction (UB if
ever executed). It is the chain machinery's deepest fall-through
for matches that the typechecker proved exhaustive, and it is
available to user code as an explicit panic primitive
(`(if cond __unreachable__ ...)` for assertions or impossible
branches). Reference site is `Term::Var { name = "__unreachable__" }`
/ form-A bare `__unreachable__`.
- **ADTs + pattern matching** (Iter 3, extended in Iter 16a/16c).
Sub-patterns of a Ctor pattern may be `Var`, `Wild`, another `Ctor`
(Iter 16a), or a literal (Iter 16c). The desugar pass flattens