docs(issues): file 0086 — Vector lane store panics (discovered, pre-existing)
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.
This commit is contained in:
56
issues/0086-vector-lane-store-unresolved-panic.md
Normal file
56
issues/0086-vector-lane-store-unresolved-panic.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# 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
|
||||
```sx
|
||||
#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.
|
||||
Reference in New Issue
Block a user