Commit Graph

2 Commits

Author SHA1 Message Date
agra
cd367847a9 ffi M5.A.next.2a.B: pack typed indexing — args[$i] substitutes call arg
Pack-fn bodies that index the pack via `args[<int_literal>]`
now resolve to the i-th call-site argument's lowered value
directly, propagating the call arg's concrete type instead
of the boxed `Any` that the `[]Any` slice path returns.

New plumbing in `src/ir/lower.zig`:

- `pack_arg_nodes: ?std.StringHashMap([]const *const Node)` on
  Lowering. Maps a pack param name (e.g. "args") to the slice
  of call-site arg AST nodes.
- `lowerComptimeCall` populates the map when the variadic
  param is heterogeneous (`is_variadic AND is_comptime`, i.e.
  the `..$args` form). Plain `args: ..Any` keeps the existing
  `[]Any` slice path so stdlib's `format`/`print` continue
  unchanged. The map is saved/restored across nested calls
  mirroring `comptime_param_nodes`.
- `packArgNodeAt(ie)` returns the call-arg node when an
  index_expr matches `<pack_name>[<comptime_int_literal>]`
  with the index in range; null otherwise (fall through to
  standard slice indexing for runtime indices or non-pack
  bases).
- `lowerIndexExpr` checks `packArgNodeAt` first; on a hit it
  lowers the call arg node directly. `inferExprType`'s
  `index_expr` arm does the parallel check so AST-level type
  inference (e.g., for field-access type checking) sees the
  concrete call-arg type.

`examples/156-pack-typed-index.sx` flips from
"field 'x' not found on type 'Any'" to `7` — `args[0].x` now
resolves through the concrete `Point` type instead of Any.

Out of scope (deferred): non-literal comptime indices
(`args[$i]` where `$i` is an arbitrary comptime expression);
`$args[$i]` in type positions (step 3); per-mono mangling
(monomorphisation stays inline-only).

195/195 example tests + `zig build test` green.
2026-05-27 13:55:19 +03:00
agra
223ec3d0b3 ffi M5.A.next.2a.A: pack typed indexing — lock in Any-untyped miss
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.
2026-05-27 13:49:44 +03:00