Files
sx/examples/1127-diagnostics-global-enum-literal-bad-variant.sx
agra 263333bd26 fix(ir): serialize enum-literal global initializers (issue 0082)
A module-global initialized with an enum literal silently zero-initialized
to the first tag (`chosen : Color = .green` read back as `.red`), and an
enum tag inside a global array/struct was rejected as non-constant. The
constant serializer had no enum-literal arm.

Add `Lowering.constEnumLiteral`: serialize an enum literal to a
`ConstantValue.int` holding the variant's tag value, resolved against the
destination enum type and respecting explicit variant values; the global's
type drives the backing width at emit time. Wired into `globalInitValue`
(scalar global) and `constExprValue` (array element / struct field / nested
aggregate). A non-enum destination or unknown variant is diagnosed loudly,
never silently zero-initialized. The compiler-injected OS/ARCH globals now
serialize to their real `.unknown` tag (6 / 4); runtime reads are unchanged
(they resolve through comptime_constants), so only the static initializer in
the pinned .ir snapshots changes.

Remove the silent `func_ref => orelse LLVMConstNull` fallbacks in the LLVM
constant emitters: aggregate func_ref leaves carry a `require_resolved` flag
(transient null in Pass 0, loud diagnostic if still unresolved in the
Pass-1.5 re-emit), a top-level func_ref global is resolved in
initVtableGlobals, and the comptime (#run) path bails loudly instead of
emitting a null function pointer.

Regression: examples/0139-types-global-enum-literal-init.sx (scalar, array,
struct field, explicit-value enum u16 stride, struct-array with enum field);
negative: examples/1127-diagnostics-global-enum-literal-bad-variant.sx.
Mark issue 0082 RESOLVED.
2026-06-04 04:52:42 +03:00

17 lines
617 B
Plaintext

// A module-global enum-literal initializer naming a variant that does not exist
// must be rejected loudly — never silently zero-initialized to the first tag.
// Regression (issue 0082): the enum-literal global serializer resolves the tag
// against the destination enum type; an unknown variant emits a diagnostic and
// fails the build instead of falling back to a null (zero-tag) initializer.
// Expected: "'.purple' is not a variant of enum 'Color'"; exit 1.
#import "modules/std.sx";
Color :: enum u8 { red; green; blue; }
bad : Color = .purple;
main :: () -> s32 {
print("{}\n", bad);
return 0;
}