fix: allow void (zero-sized) struct/tuple fields instead of crashing (issue 0150)
A struct/tuple/?T with a void field crashed the compiler: the field lowered to LLVM's unsized 'void' type, which traps getTypeSizeInBits. Lower a void field to a SIZED zero-byte [0 x i8] (fieldLLVMType) so the enclosing aggregate stays sized with identical element indices, and skip inserting a value for a void field in emitStructInit (the i64 placeholder would type-mismatch the [0 x i8] slot and corrupt the aggregate constant -> runtime bus error). Future(void) now works. Regression: examples/0190-types-void-struct-field-zero-sized.sx
This commit is contained in:
@@ -1,7 +1,18 @@
|
||||
# 0150 — a `void` struct field crashes the compiler (unsized-type SIGTRAP in LLVM)
|
||||
|
||||
> **RESOLVED.** Two coordinated changes let a `void` (zero-sized) field be a
|
||||
> legitimate construct (so `Future(void)` works): (1) `TypeLowering.fieldLLVMType`
|
||||
> (src/backend/llvm/types.zig) lowers a `void` struct/tuple/`?T` field to a SIZED
|
||||
> zero-byte `[0 x i8]` instead of LLVM's unsized `void` (which trapped
|
||||
> `getTypeSizeInBits`), keeping element count/indices identical; (2) `emitStructInit`
|
||||
> (src/backend/llvm/ops.zig) skips inserting a value for a `void` field — the i64
|
||||
> placeholder would type-mismatch the `[0 x i8]` slot and corrupt the aggregate
|
||||
> constant (the original runtime bus-error). Regression test:
|
||||
> `examples/0190-types-void-struct-field-zero-sized.sx` (covers a plain struct, a
|
||||
> generic `Box(void)`, and a tuple void element).
|
||||
|
||||
## Status
|
||||
OPEN — surfaced by Stream B1 (fibers) B1.2: `Future(void)` (needed by
|
||||
RESOLVED (was: OPEN) — surfaced by Stream B1 (fibers) B1.2: `Future(void)` (needed by
|
||||
`timeout(io, ms) -> Future(void)`) instantiates a struct with a `result: void`
|
||||
field, which hits this bug. Independent of the fibers work (a plain
|
||||
`struct { v: void; }` reproduces it standalone).
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// Repro for issue 0150 — a `void` struct field crashes the compiler with an
|
||||
// unsized-type SIGTRAP (LLVM getTypeSizeInBits). Unpinned (no expected marker)
|
||||
// because it currently aborts the compiler; pin it as a regression test once
|
||||
// the fix lands.
|
||||
#import "modules/std.sx";
|
||||
|
||||
Holder :: struct { v: void; ok: bool; }
|
||||
|
||||
main :: () -> i32 {
|
||||
h : Holder = .{ ok = true };
|
||||
if h.ok { print("ok\n"); }
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user