Files
sx/issues/0166-null-coalesce-struct-literal-default-unresolved.md
agra 2637ae98a5 docs: file issues 0164-0167 (optional/comptime bugs found during 0162 review)
0164 if <optional> no-binding folds has_value to true (silent miscompile)
0165 parenthesized nested optional ?(?T) malformed double-wrap (crash)
0166 ?? .{ } struct-literal default unresolved type (crash)
0167 comptime regToValue array-in-aggregate gap + unclean recovery
2026-06-22 19:43:55 +03:00

1.7 KiB
Raw Blame History

0166 — ?? .{ ... } struct-literal default panics with "unresolved type reached LLVM emission"

Symptom

Using a struct literal as the default of a ?? (null-coalesce) operator panics:

panic: unresolved type reached LLVM emission

in emitStructInit (exit 134 / SIGABRT). The coalesce result type is inferred correctly (the optional's child T), but that target type is NOT threaded into the RHS struct-literal lowering, so the struct_init instruction's .ty stays .unresolved and reaches codegen.

Reproduction

#import "modules/std.sx";
T :: struct { a: i64 = 0; }
mk :: () -> ?T { return null; }
main :: () { t := mk() ?? .{ a = 9 }; print("{}\n", t.a); }

Expected: 9 (null lhs → take the struct-literal default, typed as T). Observed: panic: unresolved type reached LLVM emission, exit 134.

Investigation prompt

The result type IS inferred correctly — src/ir/expr_typer.zig (~lines 413425) returns the optional's child T for the coalesce expression. The gap is in lowering: the ?? RHS struct literal is lowered without a target type. Suspected area: src/ir/lower/expr.zig lowerNullCoalesce (dispatched ~expr.zig:2417) must set the lowering target type to the lhs optional's child (T) before lowering nc.rhs, so an untyped .{ ... } literal on the RHS resolves to T the same way an assignment/return target would. Mirror however other contexts push an expected type into an untyped struct-literal lowering.

Verify: the repro prints 9; also test a present lhs (mk returns a value → prints the value's field, default not taken) and a nested-field struct literal default. Add an examples/optionals/09xx-null-coalesce-struct-literal.sx regression.