Files
sx/examples/175-generic-fn-pack-state-leak.sx
agra ec2a99a1a3 ffi issue-0050: monomorphizeFunction leaks pack-fn state — xfail lock-in
A generic fn (with `$T: Type` type params) called from inside a
pack-fn mono inherits the outer pack maps during its OWN body
lowering. Same root cause as issue-0048 — the lowering helper
doesn't save/null `pack_arg_nodes` / `pack_param_count` /
`pack_arg_types` — but on the generic-mono path
(`monomorphizeFunction`, ~line 8718) rather than
`lazyLowerFunction`.

`examples/175-generic-fn-pack-state-leak.sx` calls
`build(args: []Type, $ret: Type)` from a four-shape pack-fn. The
expected output is `len=0 / 1 / 2 / 4`; today's run reports
`len=0` for every shape because `build__void` was first
monomorphised under `probe()`'s mono (N=0) and `args.len` got
constant-folded to 0 inside the cached body. The next commit
adds the same isolation pattern to `monomorphizeFunction`.

Step 5 of the FFI plan (generic `Into(Block)` impl) needs the
`build_block_convert(args: []Type, $ret: Type) -> string` builder,
which trips this leak directly.
2026-05-27 21:44:39 +03:00

31 lines
973 B
Plaintext

// Regression: a generic function (with `$T: Type` type params)
// called from inside a pack-fn mono must NOT inherit the outer
// pack maps during its own body lowering. Before the fix landed
// in `monomorphizeFunction`, the cached mono of a generic with
// an `args`-named param had its `args.len` constant-folded to
// the arity of whichever pack shape triggered the first mono;
// every subsequent shape read the same baked-in constant.
//
// Same root cause as issue-0048 (`lazyLowerFunction`), in a
// different lowering path (`monomorphizeFunction`).
#import "modules/std.sx";
build :: (args: []Type, $ret: Type) -> string {
return concat("len=", int_to_string(args.len));
}
probe :: (..$args) -> string {
return build($args, void);
}
run_all :: () {
print("0: {}\n", probe());
print("1: {}\n", probe(true));
print("2: {}\n", probe(42, "hi"));
print("4: {}\n", probe(1, 2.0, "x", true));
}
#run run_all();
main :: () { print("rt\n"); }