From dadf80b3f19539113e884a26ac97e8b349e65001 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 16:38:01 +0300 Subject: [PATCH] =?UTF-8?q?ffi=20M5.A.next.2b.fu34.A:=20bare=20args=20+=20?= =?UTF-8?q?runtime=20index=20=E2=80=94=20lock=20in=20unresolved/LLVM=20err?= =?UTF-8?q?ors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lock-ins for follow-ups #3 (bare `args` reference) and #4 (`args[]`) from step 2b. Both share the same root cause: the pack-mono does not materialise an `[]Any` slice value for the pack name, so any body that needs `args` as a value at runtime fails. `examples/162-pack-bare-args.sx` — pack-fn body forwards `args` to a `[]Any`-typed helper. Today: "unresolved 'args' (in ... fn forward__pack_s64_string_f64)". `examples/163-pack-runtime-index.sx` — pack-fn body indexes `args[i]` with a runtime `i`. Today: LLVM verifier crash — "GEP base pointer is not a vector or a vector of pointers" — because `args` resolves to a junk Ref via the scope-lookup fall-through, and the slice-indexing path emits a GEP off that. Next commit materialises an `[]Any` slice on demand inside the mono: each pack param is boxed into Any, stored in a stack [N x Any] array, and the slice {data_ptr, len} is bound to the pack name. `args` then resolves as a runtime value the same way the pre-2b inline path used to. `args[i]` runtime indexing goes through the standard slice index path; element type is `Any` (lossy on per-position types — inherent to runtime indexing into a heterogeneous pack). 202/202 example tests + `zig build test` green. --- examples/162-pack-bare-args.sx | 29 ++++++++++++++++++ examples/163-pack-runtime-index.sx | 35 ++++++++++++++++++++++ tests/expected/162-pack-bare-args.exit | 1 + tests/expected/162-pack-bare-args.txt | 1 + tests/expected/163-pack-runtime-index.exit | 1 + tests/expected/163-pack-runtime-index.txt | 5 ++++ 6 files changed, 72 insertions(+) create mode 100644 examples/162-pack-bare-args.sx create mode 100644 examples/163-pack-runtime-index.sx create mode 100644 tests/expected/162-pack-bare-args.exit create mode 100644 tests/expected/162-pack-bare-args.txt create mode 100644 tests/expected/163-pack-runtime-index.exit create mode 100644 tests/expected/163-pack-runtime-index.txt diff --git a/examples/162-pack-bare-args.sx b/examples/162-pack-bare-args.sx new file mode 100644 index 0000000..d97e577 --- /dev/null +++ b/examples/162-pack-bare-args.sx @@ -0,0 +1,29 @@ +// Variadic heterogeneous type packs — follow-up #3 (bare `args` +// reference). The pack-mono doesn't materialise a slice value +// for the pack name itself, so any body that references `args` +// without indexing (e.g. forwarding to a `[]Any`-typed helper, +// or just computing `args.len` through a non-comptime path) +// fails with "unresolved 'args'". +// +// Next commit materialises an `[]Any` slice on demand inside +// the mono: each pack param is boxed into Any, stored in a +// stack [N x Any] array, and the slice {data_ptr, len} is bound +// to the pack name. `args` then resolves as a runtime value +// like the pre-2b inline path did. + +#import "modules/std.sx"; + +// Helper that takes a slice. Today the pack body can't pass +// `args` here because `args` isn't in scope as a value. +log_count :: (items: []Any) -> s64 { + return items.len; +} + +forward :: (..$args) -> s64 { + return log_count(args); +} + +main :: () -> s32 { + print("{}\n", forward(1, "hi", 2.5)); + return 0; +} diff --git a/examples/163-pack-runtime-index.sx b/examples/163-pack-runtime-index.sx new file mode 100644 index 0000000..939bdca --- /dev/null +++ b/examples/163-pack-runtime-index.sx @@ -0,0 +1,35 @@ +// Variadic heterogeneous type packs — follow-up #4 (runtime +// pack indexing). +// +// `args[]` substitutes through `pack_arg_nodes` (step +// 2a.B). But `args[]` — a loop counter, an +// expression — falls through to the standard slice-indexing +// path, which fails because the pack-mono doesn't materialise +// the `args` slice. Output today: "unresolved 'args'". +// +// Pairs with follow-up #3: the same `[]Any` slice +// materialisation handles both `args` bare and `args[i]` +// runtime. Element type becomes `Any` (lossy on per-position +// types — that's the inherent trade-off of runtime indexing +// into a heterogeneous pack). + +#import "modules/std.sx"; + +count_anys :: (..$args) -> s64 { + total : s64 = 0; + i : s64 = 0; + while i < args.len { + // Runtime index — should resolve through the + // materialised slice once #3+#4 lands. + x : Any = args[i]; + _ = x; + total = total + 1; + i = i + 1; + } + return total; +} + +main :: () -> s32 { + print("{}\n", count_anys(10, "hi", 2.5, true)); + return 0; +} diff --git a/tests/expected/162-pack-bare-args.exit b/tests/expected/162-pack-bare-args.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/expected/162-pack-bare-args.exit @@ -0,0 +1 @@ +1 diff --git a/tests/expected/162-pack-bare-args.txt b/tests/expected/162-pack-bare-args.txt new file mode 100644 index 0000000..7bea9a6 --- /dev/null +++ b/tests/expected/162-pack-bare-args.txt @@ -0,0 +1 @@ +/Users/agra/projects/sx/examples/162-pack-bare-args.sx:23:22: error: unresolved 'args' (in /Users/agra/projects/sx/examples/162-pack-bare-args.sx fn forward__pack_s64_string_f64) diff --git a/tests/expected/163-pack-runtime-index.exit b/tests/expected/163-pack-runtime-index.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/expected/163-pack-runtime-index.exit @@ -0,0 +1 @@ +1 diff --git a/tests/expected/163-pack-runtime-index.txt b/tests/expected/163-pack-runtime-index.txt new file mode 100644 index 0000000..542253c --- /dev/null +++ b/tests/expected/163-pack-runtime-index.txt @@ -0,0 +1,5 @@ +LLVM verification failed: GEP base pointer is not a vector or a vector of pointers + %ig.ptr = getelementptr i64, i64 %ig.data, %load7 +Load operand must be a pointer. + %ig.val = load i64, i64 %ig.ptr, align 8 +