While fixing 0083 (attempt 5) noticed a distinct, pre-existing bug: writing to a Vector component (`v.x = 1.0`) aborts with "unresolved type reached LLVM emission" in emitStore. Reading a lane works; a literal lane count triggers it, so it is NOT the lane-count class. Confirmed reproducible on the pristine pre-attempt-5 compiler (not introduced by the lane-count fix). The standard vector idiom (`.[…]` construction + component reads / arithmetic, examples/1500) is unaffected. Filed for a separate session; not worked around here.
2.8 KiB
0086 — writing to a Vector lane (v.x = …) panics with "unresolved type reached LLVM emission"
Symptom
Assigning to a component of a Vector local — v.x = 1.0 (also .y / .z /
.w) — aborts the compiler with the internal panic:
thread … panic: unresolved type reached LLVM emission — a type resolution
failure was not diagnosed/aborted
src/backend/llvm/types.zig:175 toLLVMTypeInfo (.unresolved arm @panic)
src/backend/llvm/ops.zig:358 emitStore (.pointer => toLLVMType(p.pointee))
READING a lane (x := v.x) is fine; only the STORE side hits it. The init form
(= --- undefined vs = .[…] literal) does not matter — both panic once a lane
is written. A literal lane count (Vector(3, f32)) triggers it, so this is NOT
the lane-count resolution class (issue 0083); it is a distinct bug in the
vector-lane store path, where the store's pointee type resolves to the
.unresolved sentinel instead of the lane element type.
Discovered while fixing issue 0083 (attempt 5). It is pre-existing and orthogonal
— confirmed by reproducing on the pristine pre-0083-attempt-5 compiler — so it was
NOT introduced by the lane-count fix. The standard vector idiom (construct via a
.[…] literal / a constructor function returning .[…], then read components or
use vector arithmetic, as in examples/1500-vectors-vector-math.sx) is
unaffected; only component ASSIGNMENT is broken.
Reproduction
#import "modules/std.sx";
main :: () {
v : Vector(3, f32) = .[0.0, 0.0, 0.0];
v.x = 1.0; // panic here
print("x={}\n", v.x);
}
./zig-out/bin/sx run panics. Removing the v.x = 1.0 line (read-only) prints
x=0.000000 and exits 0.
Investigation prompt
A store to a Vector lane (v.x = …) lowers a pointer-to-lane whose pointee
type reaches LLVM as .unresolved, so emitStore
(src/backend/llvm/ops.zig:358, the .pointer => toLLVMType(p.pointee) arm)
hits the .unresolved tripwire panic in
src/backend/llvm/types.zig:175. The lane READ path computes the lane element
type correctly, so compare the lvalue/store lowering for a vector-component
assignment against the rvalue/load path — the component-write path is likely
building the lane pointer's pointee from a vector .x/.y/.z/.w field
resolution that returns .unresolved (or a vector field-access that resolves the
element type on load but not on store). Find where a Vector swizzle/component
assignment lowers its destination pointer (grep for vector component handling in
lower.zig assignment lowering and in the LLVM emitStore GEP path) and resolve
the lane element type there the same way the load path does. Verify with the
repro (expect x=1.000000) plus a .[…]-init write and a write to each of
.x/.y/.z/.w on a 4-lane vector, then zig build && zig build test && bash tests/run_examples.sh green.