Files
sx/examples/161-pack-index-oob.sx
agra 2e0b97aaa5 ffi M5.A.next.2b.fu2.C: heterogeneous pack ret + OOB diagnostic
Two follow-on fixes for follow-up #2 (generic pack-fn return).

(1) `pack_arg_types` — a new type-only pack binding consulted by
`inferExprType` for `<pack_name>[<int_literal>]`. The earlier
`pack_arg_nodes`-via-synthesized-idents path lost the type
during return-type inference because the synthesized idents
("__pack_args_0" etc.) only resolve once the mono scope is set
up — but the inference runs BEFORE scope setup. Now
`monomorphizePackFn` installs `pack_arg_types[<pack>] =
arg_types` alongside the existing nodes/count maps, and
`inferExprType` consults it directly.

`foo(..$args) -> $R => args[2]` called as `foo(42, 3.2, "hello")`
now correctly returns "hello" (string) — the third element-
typed pick threads through inference to the mono ret_ty.

(2) `diagPackIndexOOB` — focused diagnostic for `args[<lit>]`
where the literal exceeds the pack arity. Pre-fix the
substitution returned null and the standard slice-indexing
fall-through emitted "unresolved args" — burying the real
cause. Now: "pack index 2 out of bounds: 'args' has 1
element" at the index span.

Tests:
- `examples/160-pack-hetero-ret.sx` — generic `$R` with non-
  zeroth heterogeneous pick (returns "hello").
- `examples/161-pack-index-oob.sx` — call passes 1 arg but
  body indexes args[2]; locks in the OOB diagnostic shape.

200/200 example tests + `zig build test` green.
2026-05-27 16:34:26 +03:00

21 lines
656 B
Plaintext

// Variadic heterogeneous type packs — out-of-bounds pack index
// is a compile-time error.
//
// `foo(..$args) -> $R => args[2]` accesses the third pack
// element. When called with fewer than 3 args, the literal index
// 2 is out of bounds for the pack's actual arity. The compiler
// detects this in `diagPackIndexOOB` and emits a focused
// diagnostic at the index span — pre-fix, the fall-through hit
// the standard slice-indexing path and produced "unresolved
// 'args'" which buried the real cause.
#import "modules/std.sx";
foo :: (..$args) -> $R => args[2];
main :: () -> s32 {
n : s64 = foo(99);
print("{}\n", n);
return 0;
}