// Regression: bare `$args` slice survives crossing a function-call // boundary — both `.len` AND per-element values come through. // // Before the fix landed in `lazyLowerFunction`, the callee's // `args.len` got constant-folded to the outer pack-fn mono's // arity. `walk(args: []Any) { return args.len; }` lazily lowered // inside `probe(..$args)`'s first mono inherited // `pack_param_count["args"] = N` from the pack — the // `.len` intercept in `lowerFieldAccess` then baked // `ret i64 N` into walk's IR. Every subsequent shape's call to // walk returned the same constant, regardless of the actual slice // it received. // // `describe(args)` walks element-by-element so a silent // truncation surfaces as a missing tail (or a different type at // some position) — not just the wrong length. // // Walking under `#run` is intentional: the bare-`$args` slice // carries `const_type` elements that only the interp materialises; // LLVM emission leaves the per-element slots as undef (4A.bare // semantics — bare-pack is comptime-only). #import "modules/std.sx"; describe :: (args: []Any) -> string { s := "["; i : i64 = 0; while i < args.len { if i > 0 { s = concat(s, ", "); } s = concat(s, type_name(args[i])); i = i + 1; } return concat(s, "]"); } probe :: (..$args) -> string { list := $args; return describe(list); } run_all :: () { print("0: {}\n", probe()); print("1: {}\n", probe(1)); print("3: {}\n", probe(1, "x", true)); print("5: {}\n", probe(1, 2.0, "x", true, 99)); } #run run_all(); main :: () { print("rt\n"); }