From 8990edbec8d3c631c84835ae1489ea09818f14b2 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 27 May 2026 17:50:02 +0300 Subject: [PATCH] =?UTF-8?q?ffi=20checkpoint:=20step=203=20done=20=E2=80=94?= =?UTF-8?q?=20type-position=20$args[$i]=20+=20intrinsics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logs the 4-commit step-3 batch (69dcee8 → 8b457ff): - 3a.A/3a.B: parser + AST + resolver for `$args[$i]` in type positions (return, param, local-var annotation). - 3a.C: extend resolution to fn-pointer type literals — the shape step 5's generic Into(Block) trampoline body needs. - 3b: `type_eq` + `has_impl` comptime intrinsics (`type_name` already existed). Both fold via `tryConstBoolCondition` so `inline if type_eq/has_impl` collapses at lower time. Step 5 (generic Into(Block) impl) is now type-system-unblocked. Step 4 (#insert pack passthrough + compile_error) is the smaller intermediate slice if needed before pushing into the stdlib refactor. Issue 0047 (`#run` stderr vs runtime stdout split) noted in "Current state" — filed but not blocking. Test count: 208/208. --- current/CHECKPOINT-FFI.md | 114 +++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 21 deletions(-) diff --git a/current/CHECKPOINT-FFI.md b/current/CHECKPOINT-FFI.md index a6a4e36..f9f04b6 100644 --- a/current/CHECKPOINT-FFI.md +++ b/current/CHECKPOINT-FFI.md @@ -6,6 +6,70 @@ add a test and make it pass — that's two commits). ## Last completed step +**M5.A.next.3 — type-position `$args[$i]` + reflection intrinsics** +(commits `69dcee8` → `8b457ff`, 5 total). + +Step 3 of the variadic heterogeneous type packs feature. +`$args[$i]` (literal index) now parses + resolves in every +type position. Three comptime intrinsics — `type_name`, +`type_eq`, `has_impl` — let pack-fn bodies branch on type +identity / protocol membership at compile time. + +| Commit | Slice | +|---|---| +| `69dcee8` | 3a.A lock-in: pre-fix parse error for `$args[$i]` in type positions | +| `3df58fe` | 3a.B fix: parser + AST (`PackIndexTypeExpr`) + `resolveTypeWithBindings` arm + sema no-op cases | +| `9137f41` | 3a.C: extend resolution to fn-pointer type literals (`fp : (*void, $args[0]) -> $args[1] = ...`) | +| `8b457ff` | 3b: `type_eq` + `has_impl` intrinsics, both wired through `tryConstBoolCondition` for `inline if` folding | + +What works: +- `(..$args) -> $args[0]` — return type position. +- `x : $args[1] = args[1]` — local-var annotation. +- `fp : (*void, $args[0]) -> $args[1] = handler;` — fn-pointer + type literal (the shape step 5's generic trampoline body needs). +- `inline if type_eq($args[0], s64) { ... }` (when the `$args[0]` + argument is in a type position — `type_eq` reads call args via + `resolveTypeArg` which routes to `resolveTypeWithBindings`). +- `has_impl(Hash, s64)` (plain protocols). +- `has_impl(Into(Block), s64)` (parameterised protocols). + +New tests: +- `examples/165-pack-type-position.sx` — return type + local + var annotation; two heterogeneous call shapes (s64+string, + string+s64) confirm distinct monos. +- `examples/166-pack-type-position-three.sx` — `args[2]` (third + element) as return type across three (s64,s64,string), + (bool,f64,s64), (string,string,bool) shapes. +- `examples/167-pack-type-fnptr.sx` — fn-pointer type literal + with `$args[$i]` in both param + return positions. +- `examples/168-pack-reflection-intrinsics.sx` — type_name, + type_eq (with inline-if folding), has_impl for both plain + (Allocator/CAllocator) and parameterised (custom Wrap(s64) + for s32) protocols. + +Out of scope (deferred): +- `$args[$i]` in EXPRESSION position (the parser only accepts + it in type positions today — `type_eq($args[0], s64)` works + because the call-arg path resolves through `resolveTypeArg`, + but bare `$args[0]` as a value would need an extra parser arm). +- `$args[$i]` in struct field types. +- has_impl static-only false-negative for protocols whose + thunks haven't been instantiated yet (relies on + `protocol_thunk_map` for plain protocols; a more robust + walk over `fn_ast_map["."]` is deferred). +- LSP "undefined variable" warnings on type names passed to + reflection intrinsics (cosmetic; sema doesn't know these + builtins accept types as args). + +Step 5 (generic `Into(Block) for Closure(..$args) -> $R` impl +in stdlib) is now unblocked from the type-system side. The +trampoline body can finally interpolate `(*void, $args[0], +$args[1], ...) -> $R` per-position types. + +208/208 example tests + `zig build test` green. + +--- + **issue-0046 fix — save/restore outer state in createComptimeFunction** (commit `248d6e6`, lock-in `13efc56`). @@ -660,7 +724,7 @@ plus 2 codegen fixes surfaced along the way.** ## Current state -- 204/204 example tests pass; `zig build test` green. +- 208/208 example tests pass; `zig build test` green. - Phase 3.0/3.1/3.2 + M1.0–M1.3 + M2.1–M2.3 + M3 + M4.0 + M4.A all landed. - Pack feature step 1 done (1c.A → 1d.B; commits bb6eca6 → 08feb60). - Pack feature step 2 done — typed `args[$i]` at literal indices @@ -673,36 +737,44 @@ plus 2 codegen fixes surfaced along the way.** - issue-0045 (comptime-fn-with-return verifier crash) fixed (9e78790). - issue-0046 (nested-comptime-call + return) FIXED (248d6e6) — `createComptimeFunction` now saves/restores outer state. +- issue-0047 (#run stderr vs runtime stdout split) FILED. +- Pack feature step 3 done — type-position `$args[$i]` + + reflection intrinsics (`type_name`, `type_eq`, `has_impl`). - iOS-sim chess running end-to-end (verified post-step-2b screencap). - Chess on macOS / iOS-sim / Android all build and run. ## Pack feature — next slice options -Step 2 + all four follow-ups done. Pack-fns are functionally -complete on the mono path: typed indexing, generic returns, +Steps 1, 2 (+ four follow-ups), and 3 all done. Pack-fns are +functionally complete: typed indexing, generic returns, heterogeneous picks, OOB diagnostics, bare/runtime `args` -access, mixed comptime+pack — all work. - -Step 3 ("Type-reflection intrinsics") is the natural next: -- `$args[$i]` in TYPE positions (param types, return types, - fn-pointer types, struct fields). Unlocks the block-trampoline - body in stdlib's generic `Into(Block) for Closure(..$args) -> - $R` impl — the body needs `typed_fn : (*void, $args[0], - $args[1]) -> $R = xx ...` per-position type interpolation. -- `type_name`, `type_eq`, `has_impl` comptime intrinsics. +access, mixed comptime+pack, `$args[$i]` in type positions, +type-reflection intrinsics. Step 4 (`#insert` pack passthrough + `compile_error`) is a -parser/interp tweak letting builders raise build-time -diagnostics from inside `#insert` bodies. +small parser/interp tweak letting builders accept `$args` as a +comptime `[]Type` value AND raise build-time diagnostics from +inside `#insert` bodies. Prep work for step 5/6. -Step 5 (generic `Into(Block)` impl) and step 6 (stdlib -`print`/`format` refactor) are the visible payoff slices, -gated on step 3 (and partially step 4). +Step 5 (generic `Into(Block)` impl) — the visible end-user +payoff. Replaces stdlib's per-signature hand-rolled Into +impls with ONE generic that the compiler emits per-call-shape. +Body uses `$args[$i]` in fn-pointer type positions for the +trampoline signature (step 3 unblocked this) + emits a +trampoline-fn per mono. -Outstanding items not blocking step 3: -- Non-literal comptime args in mixed-mode pack-fns (degrades - to a `?` mangle segment today — would need comptime - evaluation for proper handling). +Step 6 (stdlib `print` / `format` refactor) — rewrite the +existing `($fmt: string, args: ..Any)` signatures to use the +new pack feature. Compile-time arity and type checking +instead of runtime Any boxing. + +Outstanding items not blocking the next slice: +- `$args[$i]` in EXPRESSION position (parser limitation). +- Non-literal comptime args in mixed-mode pack-fns. +- LSP "undefined variable" warnings on type-name args to + reflection intrinsics (cosmetic). +- has_impl static-only false-negative for un-instantiated + plain protocols. **M4.0 — context.allocator threading** (4 commits this session): - `__sx_allocator: Allocator` prepended at field index 0 of every