Attempts 1–4 fixed the array-dimension paths but the same length-0 fabrication class survived on every other site that resolves a compile-time integer. Unify them all on the single shared `program_index.evalConstIntExpr` so they cannot diverge: - All three Vector lane resolvers (resolveTypeCallWithBindings, resolveParameterizedWithBindings, resolveArrayLiteralType) and both generic value-param binders (instantiateGenericStruct, instantiateTypeFunction) hand-rolled an `else => 0` switch. A module-const lane `Vector(N, f32)` fabricated a 0-lane `<0 x float>` (LLVM "huge alignment" abort); a value-param `Vec(N, f32)` fabricated a 0 binding / wrong mangled name. They now fold through the shared evaluator and emit a clean diagnostic + `.unresolved` on a non-const operand (resolveVectorLane / resolveValueParamArg) — never 0. - evalComptimeInt (inline-for bounds) delegated to the shared evaluator, so `inline for 0..M` / `0..(M+1)` fold like array dims. The `<pack>.len` leaf moved into the shared folder via a new `ctx.lookupPackLen`. - The unknown-type semantic checker no longer walks a value-param position (`Vector(N, …)` / `Vec(N, …)`) as a type name (was reporting "unknown type 'N'"). - The parameterized-type-arg parser and the function-body lookahead (hasFnBodyAfterArrow) accept a const-EXPRESSION in a value position, so `Vector(M + 1, f32)` and `[M + 1]T` parse as a return type too (the latter a pre-existing array-dim sibling that the same heuristic broke). Regressions: examples/1501 (named-const + const-expr lane, direct + alias, 3/4-lane reads), 1502 (runtime lane clean-halts, exit 1, no LLVM crash), 0207 (Vec(N)/Vec(M+1) == Vec(3) instantiation), 0610 (inline-for const bounds). Shared-evaluator unit test extended with the pack-len arm. zig build && zig build test && bash tests/run_examples.sh: 395 passed, 0 failed.
36 lines
1.5 KiB
Plaintext
36 lines
1.5 KiB
Plaintext
// A `Vector` lane count from a named const or a constant-foldable expression
|
|
// resolves to the SAME layout as a literal lane — DIRECT (param / return type)
|
|
// and via a type ALIAS. A 3-lane (named const `N`) and a 4-lane (const expr
|
|
// `M + 1`) prove the lane VALUE is folded, not fabricated: reading `.w` requires
|
|
// the 4-lane vector to actually have four lanes.
|
|
//
|
|
// Regression (issue 0083): the stateful Vector lane resolvers hand-rolled an
|
|
// `else => 0` switch, so a module-const lane (`Vector(N, f32)`) lowered a 0-lane
|
|
// `<0 x float>` and died in LLVM verification ("huge alignment values are
|
|
// unsupported"); a const-expr lane (`Vector(M + 1, f32)`) was rejected at parse.
|
|
// Both now fold through the single shared const-int evaluator
|
|
// (`program_index.evalConstIntExpr`) — the same one the array-dimension path
|
|
// uses — so a named-const / const-expr lane is identical to a literal lane.
|
|
#import "modules/std.sx";
|
|
|
|
N :: 3;
|
|
M :: 3;
|
|
|
|
LaneAlias :: Vector(N, f32); // ALIAS: 3-lane via named const.
|
|
ExprAlias :: Vector(M + 1, f32); // ALIAS: 4-lane via const expression.
|
|
|
|
mk3 :: () -> Vector(N, f32) { .[1.0, 2.0, 3.0] } // DIRECT named-const lane.
|
|
mk4 :: () -> Vector(M + 1, f32) { .[1.0, 2.0, 3.0, 4.0] } // DIRECT const-expr lane.
|
|
|
|
main :: () {
|
|
a := mk3();
|
|
print("direct3: {} {} {}\n", a.x, a.y, a.z);
|
|
b := mk4();
|
|
print("direct4: {} {} {} {}\n", b.x, b.y, b.z, b.w);
|
|
|
|
c : LaneAlias = .[5.0, 6.0, 7.0];
|
|
print("alias3: {}\n", c.z);
|
|
d : ExprAlias = .[5.0, 6.0, 7.0, 8.0];
|
|
print("alias4: {}\n", d.w);
|
|
}
|