From 5316bf76e1867093793a246692750fe564f60d0f Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 21:45:15 +0300 Subject: [PATCH] ffi issue-0050: monomorphizeFunction isolates pack-fn mono state Adds the same save+null+defer-restore block at the top of `monomorphizeFunction` that landed in `lazyLowerFunction` for issue-0048. The outer pack-fn's `pack_arg_nodes` / `pack_param_count` / `pack_arg_types` / `inline_return_target` are now suppressed for the duration of the generic mono's body lowering and restored on exit. `examples/175-generic-fn-pack-state-leak.sx` flips green (len=0/1/2/4 across the four pack shapes); suite stays at 215/215. --- src/ir/lower.zig | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ir/lower.zig b/src/ir/lower.zig index ed82ab9..25513b3 100644 --- a/src/ir/lower.zig +++ b/src/ir/lower.zig @@ -8730,6 +8730,29 @@ pub const Lowering = struct { const saved_defer_base = self.func_defer_base; const saved_block_terminated = self.block_terminated; const saved_target = self.target_type; + // Pack-fn mono state is lexical to the pack-fn body. A generic + // function called from inside a pack-fn mono (e.g. + // `build(args: []Type, $ret: Type)` invoked from + // `probe(..$args) { build($args, void) }`) must not inherit the + // caller's pack maps — `lowerFieldAccess`'s `.len` + // intercept would otherwise constant-fold the callee's + // same-named param to whichever shape triggered the first mono + // and bake the wrong arity into the cached IR. Same shape of + // fix as `lazyLowerFunction` (issue-0048, commit 0ede097). + const saved_pan = self.pack_arg_nodes; + const saved_ppc = self.pack_param_count; + const saved_pat = self.pack_arg_types; + const saved_iri = self.inline_return_target; + self.pack_arg_nodes = null; + self.pack_param_count = null; + self.pack_arg_types = null; + self.inline_return_target = null; + defer { + self.pack_arg_nodes = saved_pan; + self.pack_param_count = saved_ppc; + self.pack_arg_types = saved_pat; + self.inline_return_target = saved_iri; + } self.func_defer_base = self.defer_stack.items.len; self.block_terminated = false;