# 0190 — void failable (`-> !`) implicit fall-through leaves the error slot uninitialized **Status:** OPEN ## Symptom A `-> !` (void failable) function that exits by **implicit fall-through** (no explicit `return;`) does not initialize its error-channel slot, so a caller (or `main`) reads a non-zero garbage tag and reports a phantom unhandled error. - Observed: `main :: () -> ! { print("ok\n"); }` prints `ok` then `error: unhandled error reached main: error.` and exits **1**. - Expected: exit **0** (specs.md §11: "the exit code is `0` for void / `-> !` success"). Adding an explicit trailing `return;` makes it exit 0. This is the silent-uninitialized-slot failure mode: the success path should write "no error" into the channel just like an explicit `return;` does, but the fall-through path skips it. ## Reproduction ```sx #import "modules/std.sx"; main :: () -> ! { print("ok\n"); } ``` Run: `./zig-out/bin/sx run repro.sx` → prints `ok`, then `error: unhandled error reached main: error.`, exit 1 (should be 0). A non-`main` void failable shows the same uninitialized slot downstream: ```sx #import "modules/std.sx"; noop :: () -> ! { } // falls through, no `return;` main :: () { noop() catch (e) { print("phantom: {}\n", e); } // fires spuriously } ``` Workaround (confirms root cause): an explicit `return;` at the end of the `-> !` body initializes the slot and the phantom error disappears. ## Investigation prompt The error channel for a `-> !` function is the last slot of the return aggregate (specs.md §12 ABI). An explicit `return;` lowers to a write of the "no error" sentinel into that slot; the **implicit fall-through** exit path (end of body with no `return`) apparently omits that write, leaving the slot whatever was on the stack. Likely area: the function-epilogue / failable-return lowering in `src/ir/lower/` (the path that synthesizes the implicit return for a body that falls off the end — search for where a void/`-> !` function's trailing fall-through is lowered, and where the error slot's "no error" sentinel is written on the explicit-`return;` path). The fix: the implicit fall-through of a failable function must initialize the error slot to "no error" exactly like `return;` does. Verification: the two repros above must exit 0 / not fire the catch; `examples/errors/1026-errors-failable-main.sx` (which currently passes only because it ends in `return;`) must keep passing. Add a regression example: a `-> !` function (and a `main :: () -> !`) that succeeds by fall-through with no explicit `return;`. (Found by adversarial review during the tuple-syntax-cutover docs pass, commit `989e18b7`. Pre-existing — independent of the tuple change.)