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.
This commit is contained in:
30
examples/175-generic-fn-pack-state-leak.sx
Normal file
30
examples/175-generic-fn-pack-state-leak.sx
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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"); }
|
||||
Reference in New Issue
Block a user