From 223ec3d0b3de7b586c7bb140fff4b0e911221783 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 13:49:44 +0300 Subject: [PATCH] =?UTF-8?q?ffi=20M5.A.next.2a.A:=20pack=20typed=20indexing?= =?UTF-8?q?=20=E2=80=94=20lock=20in=20Any-untyped=20miss?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 2 of the variadic heterogeneous type packs feature: typed runtime indexing (`args[$i]` at comptime-known `$i`). Today's pack-fn body lowers `args[i]` through the `[]Any` slice path — the static type returned is `Any`, so any downstream field access / typed-coercion / further indexing fails the moment it needs more than primitive auto-unboxing. `examples/156-pack-typed-index.sx` pins the simplest visible failure: `args[0].x` on a struct-typed call arg trips "field 'x' not found on type 'Any'" at the field-access site because AST-level type inference for `args[0]` returns Any. Next commit teaches `lowerIndexExpr` (and `inferExprType` for the same shape) to detect an index_expr whose base is a pack-name binding from the enclosing comptime call AND whose index is a comptime int literal — substitutes the i-th call-site arg's lowered value directly, propagating the call arg's concrete type through field access, typed assignments, and further indexing. The `[]Any` slice path stays as the runtime-indexed fallback for `args[i]` where `i` is not a comptime constant. 195/195 example tests + `zig build test` green. --- examples/156-pack-typed-index.sx | 32 ++++++++++++++++++++++++ tests/expected/156-pack-typed-index.exit | 1 + tests/expected/156-pack-typed-index.txt | 1 + 3 files changed, 34 insertions(+) create mode 100644 examples/156-pack-typed-index.sx create mode 100644 tests/expected/156-pack-typed-index.exit create mode 100644 tests/expected/156-pack-typed-index.txt diff --git a/examples/156-pack-typed-index.sx b/examples/156-pack-typed-index.sx new file mode 100644 index 0000000..a944582 --- /dev/null +++ b/examples/156-pack-typed-index.sx @@ -0,0 +1,32 @@ +// Variadic heterogeneous type packs — step 2: typed pack indexing. +// +// `args[$i]` (with `$i` a comptime-known integer) inside a pack-fn +// body should resolve to the i-th call-site argument with its +// CONCRETE type, not the boxed `Any` that today's `[]Any` slice +// path yields. Without typed access, downstream operations on the +// element (field access, typed coercion, passing to a typed slot) +// either fail with "field 'X' not found on type 'Any'" or silently +// box/unbox through Any. +// +// This file pins today's failure: `args[0].x` on a struct-typed +// call arg trips "field 'x' not found on type 'Any'" because the +// AST-level type inference for `args[0]` returns Any. +// +// Next commit teaches `lowerIndexExpr` to detect a pack-name base +// with a comptime-int-literal index and substitute the i-th +// call-site arg's lowered value directly — propagating the call +// arg's real type through field access, typed assignments, and +// further indexing. + +#import "modules/std.sx"; + +Point :: struct { x: s64; y: s64; } + +get_x :: (..$args) -> s64 => args[0].x; + +main :: () -> s32 { + p := Point.{ x = 7, y = 9 }; + n := get_x(p); + print("{}\n", n); + return 0; +} diff --git a/tests/expected/156-pack-typed-index.exit b/tests/expected/156-pack-typed-index.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/expected/156-pack-typed-index.exit @@ -0,0 +1 @@ +1 diff --git a/tests/expected/156-pack-typed-index.txt b/tests/expected/156-pack-typed-index.txt new file mode 100644 index 0000000..ab39be2 --- /dev/null +++ b/tests/expected/156-pack-typed-index.txt @@ -0,0 +1 @@ +/Users/agra/projects/sx/examples/156-pack-typed-index.sx:25:30: error: field 'x' not found on type 'Any'