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.
21 lines
656 B
Plaintext
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;
|
|
}
|