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
+15
View File
@@ -73,6 +73,20 @@ pub fn install(env: &mut crate::Env) {
},
);
// Iter 16d: `__unreachable__` is the polymorphic bottom value.
// Type: `forall a. a`. Used by the desugar pass as the chain
// terminator of an exhaustive match, and available to user code as
// a primitive panic point. Codegen lowers it to LLVM `unreachable`.
// It is a value, not a fn — reference site is `(var __unreachable__)`,
// not `(app __unreachable__)`.
env.globals.insert(
"__unreachable__".into(),
Type::Forall {
vars: vec!["a".into()],
body: Box::new(Type::Var { name: "a".into() }),
},
);
env.effect_ops.insert(
"io/print_int".into(),
EffectOpSig {
@@ -130,6 +144,7 @@ pub fn list() -> Vec<(&'static str, &'static str)> {
(">", "(Int, Int) -> Bool"),
(">=", "(Int, Int) -> Bool"),
("not", "(Bool) -> Bool"),
("__unreachable__", "forall a. a"),
("io/print_int", "(Int) -> Unit !IO [effect op]"),
("io/print_bool", "(Bool) -> Unit !IO [effect op]"),
("io/print_str", "(Str) -> Unit !IO [effect op]"),