From 69dcee88cd21efdb0b031e18289df153a8281458 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 17:20:37 +0300 Subject: [PATCH] =?UTF-8?q?ffi=20M5.A.next.3a.A:=20$args[$i]=20in=20type?= =?UTF-8?q?=20positions=20=E2=80=94=20expected-failing=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 3 of the variadic heterogeneous type packs feature. `$args[$i]` (with `$i` a literal integer for the first slice) should resolve to the i-th element type of the active pack binding in every type position: return types, param types, local var annotations, fn-pointer type literals, struct fields. Today the parser hits "expected '{'" at the `$args[]` token because the `$` arm in `parseTypeExpr` only recognises plain generic names (`$T`, `$T/Eq/Hashable`). After ``, an opening `[` is unexpected. `examples/165-pack-type-position.sx` exercises two type positions per mono — a return type `-> $args[0]` AND a local var annotation `second : $args[1] = args[1]` — so the parser change must cover more than the trailing return arrow. Two call shapes (`swap_take(42, "ignored")` and `swap_take("first", 99)`) confirm heterogeneous monos pick distinct concrete types per position. Cadence shape 2: the expected output is the WORKING output ("42 first"); pre-fix the diff vs the parser-error output fails. Next commit lands the parser + resolver changes and the test flips green. 204/204 + 1 expected-failing = 205 total. `zig build test` green. --- examples/165-pack-type-position.sx | 39 ++++++++++++++++++++++ tests/expected/165-pack-type-position.exit | 1 + tests/expected/165-pack-type-position.txt | 1 + 3 files changed, 41 insertions(+) create mode 100644 examples/165-pack-type-position.sx create mode 100644 tests/expected/165-pack-type-position.exit create mode 100644 tests/expected/165-pack-type-position.txt diff --git a/examples/165-pack-type-position.sx b/examples/165-pack-type-position.sx new file mode 100644 index 0000000..f1f1912 --- /dev/null +++ b/examples/165-pack-type-position.sx @@ -0,0 +1,39 @@ +// Variadic heterogeneous type packs — step 3: `$args[$i]` in +// type positions. +// +// `$args[$i]` resolves to the i-th element type of the active +// pack binding wherever a type expression is expected: +// - return type: `-> $args[0]` +// - local var annotation: `x : $args[1] = ...` +// - (later: param types, fn-pointer types, struct field types) +// +// Today's parser hits "expected '{'" at the `$args[0]` token in +// the return type position because the `$` arm only +// accepts plain generic names; `[]` after the name isn't +// recognised. This file pins that rejection. Next commit teaches +// the parser to accept `$[]` and adds a new +// `PackIndexTypeExpr` AST node; `resolveTypeWithBindings` +// consults the active `pack_arg_types` map. +// +// The body intentionally exercises TWO positions per mono — the +// return type AND a local annotation — so the parser change has +// to cover more than just the trailing return arrow. + +#import "modules/std.sx"; + +swap_take :: (..$args) -> $args[0] { + second : $args[1] = args[1]; + // `second` is bound and typed — confirms the local-annotation + // path also resolves. The body returns args[0] (statically + // typed as $args[0]). + return args[0]; +} + +main :: () -> s32 { + // Heterogeneous call shapes — each picks a different concrete + // pair, gets its own mono. + a : s64 = swap_take(42, "ignored"); // $args[0] = s64, $args[1] = string + b : string = swap_take("first", 99); // $args[0] = string, $args[1] = s64 + print("{} {}\n", a, b); + return 0; +} diff --git a/tests/expected/165-pack-type-position.exit b/tests/expected/165-pack-type-position.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tests/expected/165-pack-type-position.exit @@ -0,0 +1 @@ +0 diff --git a/tests/expected/165-pack-type-position.txt b/tests/expected/165-pack-type-position.txt new file mode 100644 index 0000000..3892788 --- /dev/null +++ b/tests/expected/165-pack-type-position.txt @@ -0,0 +1 @@ +42 first