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.
This commit is contained in:
agra
2026-05-27 21:45:15 +03:00
parent ec2a99a1a3
commit 5316bf76e1

View File

@@ -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 `<pack_name>.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;