ffi issue-0045 fix: inline-return slot for comptime-call bodies
`lowerComptimeCall` now scans the body for `return` statements
via `fnBodyHasReturn`. When found, it allocates a stack slot
typed to the fn's return type and installs it as
`self.inline_return_target` before lowering the body.
`lowerReturn` checks `inline_return_target` first:
- If set, it stores the coerced return value into the slot,
drains pending defers, sets `block_terminated = true`, and
returns without emitting a `ret` into the caller's basic
block.
- Otherwise it emits the standard `ret` as before.
After the body lowers, the inliner either returns the
tail-expression value (existing fast path — bodies with no
`return` skip the slot entirely) or loads the slot when
`block_terminated` is set.
Why the bug was invisible until now: `format`/`print` and
every other stdlib comptime fn use arrow form (`=> expr`) or
`#insert`-only bodies — no `return` statement, no path through
`lowerReturn`. Step 1.b of the pack feature made `..$args`
parseable; the natural smoke test
`foo :: (..$args) -> s64 { return 42; }` was the first
comptime-fn body to take the `return`-with-trailing-statements
path, surfacing the LLVM verifier crash.
`examples/issue-0045.sx` flips from the lock-in failure to
`42`. 194/194 example tests + `zig build test` green.
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
**FIXED.** `lowerComptimeCall` now allocates a result slot when
|
||||
the body contains a `return` statement and reroutes
|
||||
`lowerReturn` to store into it instead of emitting `ret` into the
|
||||
caller's basic block. Regression test:
|
||||
[examples/issue-0045.sx](../examples/issue-0045.sx).
|
||||
|
||||
# Symptom
|
||||
|
||||
Calling a fn declared with `..$args` (variadic heterogeneous type
|
||||
|
||||
Reference in New Issue
Block a user