From fc8a8c3f2e62b69af441afb91dc66af536309760 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 16:43:04 +0300 Subject: [PATCH] =?UTF-8?q?ffi=20M5.A.next.2b.fu1.A:=20mixed=20comptime+pa?= =?UTF-8?q?ck=20=E2=80=94=20lock=20in=20unresolved-tag=20miss?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up #1 from step 2b: pack-fns that mix a non-pack comptime param with the trailing pack (e.g. `tagged($tag: s32, ..$args)`). Today's `isPackFn` requires the pack to be the ONLY comptime param; mixed shapes fall through to the inline `lowerComptimeCall` path. That path adds non-string comptime params to `comptime_param_nodes` for #insert substitution but does NOT bind them as runtime locals, so the body's bare `tag` reference hits "unresolved 'tag'" at the call site. Next commit: - Relax `isPackFn` to "exactly one trailing pack + any number of non-pack comptime params" so the mono path takes over. - Fold comptime VALUES into the mangled name (`tagged(7, ...)` and `tagged(9, ...)` get distinct monos so each body sees its own comptime constants). - Bind comptime args as both `comptime_param_nodes` (for #insert substitution) AND runtime locals (for bare-name references). String literals stay as string locals; int/bool/float literals become typed locals of the appropriate primitive type. This is the load-bearing prerequisite for step 6 (stdlib `print`/`format` refactor to `(\$fmt, ..\$args)`) — without mixed-mode mono support, stdlib stays on the inline path forever. 203/203 example tests + `zig build test` green (the lock-in captures the wrong-shape diagnostic as the snapshot to flip). --- examples/164-pack-mixed-comptime.sx | 29 +++++++++++++++++++++ tests/expected/164-pack-mixed-comptime.exit | 1 + tests/expected/164-pack-mixed-comptime.txt | 1 + 3 files changed, 31 insertions(+) create mode 100644 examples/164-pack-mixed-comptime.sx create mode 100644 tests/expected/164-pack-mixed-comptime.exit create mode 100644 tests/expected/164-pack-mixed-comptime.txt diff --git a/examples/164-pack-mixed-comptime.sx b/examples/164-pack-mixed-comptime.sx new file mode 100644 index 0000000..a49adf9 --- /dev/null +++ b/examples/164-pack-mixed-comptime.sx @@ -0,0 +1,29 @@ +// Variadic heterogeneous type packs — follow-up #1 (mixed +// `$comptime + ..$args` pack-fn signatures). +// +// Today's `isPackFn` rejects pack-fns that mix any other +// comptime param with the trailing pack — they fall through +// to the inline `lowerComptimeCall` path. The inline path +// doesn't bind non-string comptime params as runtime locals, +// so a body that uses both `$tag` (s32) AND `..$args` fails +// at the bare-name lookup of `tag`. +// +// Next commit relaxes `isPackFn` to accept "exactly one +// trailing pack + any number of non-pack comptime params" and +// `monomorphizePackFn` folds the comptime VALUES into the +// mangled name (so distinct calls of `tagged(7, ...)` vs +// `tagged(9, ...)` get distinct monos), then binds the +// comptime values as both comptime substitutions and runtime +// locals (for body code that references them by name). + +#import "modules/std.sx"; + +tagged :: ($tag: s32, ..$args) -> s64 { + return tag * 100 + args.len; +} + +main :: () -> s32 { + print("{}\n", tagged(7, 1, 2, 3)); // 7*100 + 3 = 703 + print("{}\n", tagged(9)); // 9*100 + 0 = 900 + return 0; +} diff --git a/tests/expected/164-pack-mixed-comptime.exit b/tests/expected/164-pack-mixed-comptime.exit new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/tests/expected/164-pack-mixed-comptime.exit @@ -0,0 +1 @@ +1 diff --git a/tests/expected/164-pack-mixed-comptime.txt b/tests/expected/164-pack-mixed-comptime.txt new file mode 100644 index 0000000..6c400b9 --- /dev/null +++ b/tests/expected/164-pack-mixed-comptime.txt @@ -0,0 +1 @@ +/Users/agra/projects/sx/examples/164-pack-mixed-comptime.sx:22:12: error: unresolved 'tag' (in /Users/agra/projects/sx/examples/164-pack-mixed-comptime.sx fn main)