From 618aa3724dfa17aedee9b786dee9c57554a350ca Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 13:22:01 +0300 Subject: [PATCH] ffi checkpoint: issue-0045 fix + step 1 wrap-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logs the issue-0045 fix (inline-return slot for comptime-call bodies, commits 3d32ab0 + 9e78790) — the LLVM verifier crash that surfaced when probing step 2 of the pack feature. Test count now 194/194 with the new regression test. --- current/CHECKPOINT-FFI.md | 43 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/current/CHECKPOINT-FFI.md b/current/CHECKPOINT-FFI.md index 4b18b0e..42a65e3 100644 --- a/current/CHECKPOINT-FFI.md +++ b/current/CHECKPOINT-FFI.md @@ -6,6 +6,45 @@ add a test and make it pass — that's two commits). ## Last completed step +**issue-0045 fix — inline-return slot for comptime-call bodies** +(commit `9e78790`, lock-in `3d32ab0`). + +Surfaced by probing step-2 territory of the pack feature: any +comptime fn (`is_comptime` param, non-void return) with a block +body containing `return X;` trips LLVM's "Terminator found in +the middle of a basic block" verifier. `lowerComptimeCall` +inlines the body's statements directly into the caller, and +`lowerReturn` emits `ret` into the caller's basic block — but +the caller still has trailing instructions. + +Root cause was broader than packs: `format`/`print` use arrow +form (`=> expr`) or `#insert`-only bodies, so no stdlib comptime +fn took the `return`-with-trailing-statements path. Step 1.b +made `..$args` parseable; the natural smoke test +`foo :: (..$args) -> s64 { return 42; }` was the first body to +hit it. + +Fix in `src/ir/lower.zig`: +- New `inline_return_target: ?InlineReturnInfo` on Lowering. + `InlineReturnInfo` carries a result slot Ref + the ret_ty. +- `lowerComptimeCall` calls `fnBodyHasReturn` to scan the body; + when true, it allocates a slot, installs it as + `inline_return_target`, lowers the body, and either returns + the tail expression value OR loads the slot when + `block_terminated` is set. Pure tail-expression bodies skip + the slot entirely — keeps the common `#insert`-based path + unchanged. +- `lowerReturn` checks `inline_return_target` first: when set, + stores the coerced value into the slot, drains pending + defers, sets `block_terminated = true`, and returns without + emitting `ret`. Otherwise the standard `ret` path runs. + +Regression test `examples/issue-0045.sx` flips from the LLVM +verifier crash to `42`. 194/194 example tests + `zig build test` +green. + +--- + **M5.A.next.1d.B — variadic heterogeneous type packs: pack-aware impl matching** (commit `08feb60`). @@ -394,8 +433,10 @@ plus 2 codegen fixes surfaced along the way.** ## Current state -- 185/185 example tests pass; `zig build test` green. +- 194/194 example tests pass; `zig build test` green. - Phase 3.0/3.1/3.2 + M1.0–M1.3 + M2.1–M2.3 + M3 + M4.0 + M4.A all landed. +- Pack feature step 1 done (1c.A → 1d.B; commits bb6eca6 → 08feb60). +- issue-0045 (comptime-fn-with-return verifier crash) fixed (9e78790). - Chess on macOS / iOS-sim / Android all build and run. **M4.0 — context.allocator threading** (4 commits this session):