Step 3 first slice. `$<pack>[<int_literal>]` now parses in
every type position and resolves against the active pack
binding (`pack_arg_types` map set up by `monomorphizePackFn`).
Plumbing:
- src/ast.zig: new `PackIndexTypeExpr { pack_name, index }`
AST node + `pack_index_type_expr` variant in `Data`.
- src/parser.zig: in `parseTypeExpr`'s `$<ident>` arm, peek
for `[`. If found, parse a non-negative `int_literal` index
followed by `]` and emit a `pack_index_type_expr` node.
Plain `$T` / `$T/Eq` paths unchanged.
- src/ir/lower.zig::resolveTypeWithBindings: handles
`pack_index_type_expr` first — looks up the pack name in
`pack_arg_types`, returns `arg_tys[index]` when in range.
OOB and "no active pack binding" cases emit focused
diagnostics at the node span.
- src/ir/type_bridge.zig::resolveAstType: handles the same
node but falls back to `.s64` with a stderr note — the bare
type_bridge has no access to lowering state. Pack-aware
callers route through `resolveTypeWithBindings`.
- src/sema.zig: adds `pack_index_type_expr` to the no-op
arms in `analyzeNode` and `findNodeAtOffset` so the sema
pass doesn't reject the new variant.
Tests:
- examples/165-pack-type-position.sx (lock-in from 69dcee8)
flips from parse error to "42 first". Exercises both a
return-type position (-> $args[0]) AND a local-var
annotation (second : $args[1] = args[1]); two
heterogeneous call shapes confirm distinct monos pick
distinct concrete types per pack index.
- examples/166-pack-type-position-three.sx — three-element
pack with $args[2] (third element) as return type. Three
call shapes: (s64,s64,string), (bool,f64,s64),
(string,string,bool). Prints "third 99 false".
Out of scope (deferred):
- $args[$i] where $i is a comptime-bound expression (only
literal int supported in this slice).
- $args[$i] in fn-pointer type LITERALS (works for named
decls but nested fn type expressions need an audit).
- $args[$i] in struct field types.
206/206 example tests + `zig build test` green.
22 lines
817 B
Plaintext
22 lines
817 B
Plaintext
// Variadic heterogeneous type packs — step 3 complex smoke.
|
|
//
|
|
// Three-element pack with `$args[2]` (the third element) used in
|
|
// the return-type position. Confirms:
|
|
// - Multi-arg packs index past the zeroth element correctly.
|
|
// - Three distinct call shapes get three distinct monos.
|
|
// - The return-type slot is correctly substituted per-mono so
|
|
// the inferred caller type matches what the body actually
|
|
// returns (string / s64 / bool here).
|
|
|
|
#import "modules/std.sx";
|
|
|
|
third :: (..$args) -> $args[2] => args[2];
|
|
|
|
main :: () -> s32 {
|
|
a := third(1, 2, "third"); // (s64, s64, string) → "third"
|
|
b := third(true, 3.14, 99); // (bool, f64, s64) → 99
|
|
c := third("a", "b", false); // (string, string, bool) → false
|
|
print("{} {} {}\n", a, b, c);
|
|
return 0;
|
|
}
|