Emit a warning when a `match` expression on an ADT value misses one
or more constructors and lacks an `else`/`_` clause. Behaviour is
non-fatal — the match still runs, the warning goes to stderr.
- spec/evaluator.sx: helpers `match-clause-is-else?`, `match-clause-ctor-name`,
`match-warn-non-exhaustive`, `match-check-exhaustiveness`. The latter
reads the `*adt-registry*` (already populated by `define-type`),
collects constructor patterns from clauses, and dedupes via an
`*adt-warned*` env-bound dict so each (type, missing-set) warns once.
Wired into `step-sf-match` via a `do` block before clause dispatch.
- hosts/javascript/platform.py: `host-warn` primitive (`console.warn`)
+ matching `hostWarn` js-id helper so the JS-transpiled spec code
can call it directly. Spec code reaches JS via `sx_build target=js`.
- hosts/ocaml/lib/sx_runtime.ml + sx_primitives.ml: `host-warn` runtime
helper (`prerr_endline`) and registered primitive.
- hosts/ocaml/lib/sx_ref.ml: HAND-PATCHED. `step_sf_match` now calls
a hand-written `match_check_exhaustiveness` that handles both
`AdtValue` and back-compat dict-shape ADT values. The OCaml side
is *not* retranspiled because regenerating sx_ref.ml drops
several preamble fixes (seq_to_list, string->symbol mangling,
empty-dict literal bug). Future retranspile must reapply this patch.
- spec/tests/test-adt.sx: 5 new tests covering exhaustive,
non-exhaustive (warning is non-fatal), `else` suppression,
partial coverage with one missing constructor, and `_` wildcard
suppression. Tests assert return values only — warnings go to
stderr and are not captured.
Warning format: `[sx] match: non-exhaustive — TypeName: missing Ctor1, Ctor2`
Both hosts emit identical messages.
Tests: OCaml 4540 → 4545 (+5), JS 2586 → 2591 (+5). Zero regressions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>