# 0082 - global enum-literal initializer silently zero-initializes > **RESOLVED.** > **Root cause:** `Lowering.globalInitValue` (`src/ir/lower.zig`) carried an > `.enum_literal => null` carve-out: any enum-literal global initializer returned > a null payload, which the LLVM/interp emitters turn into a zero-initialized > global — so `chosen : Color = .green` read back as the first tag (`.red`). > `constExprValue` had no enum-literal arm either, so an enum tag inside a global > array (`[2]Color = .[.green, .blue]`) or struct field made the whole aggregate > look non-constant and the global was rejected outright. > **Fix:** a new `Lowering.constEnumLiteral` serializes an enum literal to a > `ConstantValue.int` holding the variant's tag value, resolved against the > destination enum type and respecting explicit variant values (`enum { a; b :: > 5; }`); the global's type drives the backing width at emit time. Wired into both > `globalInitValue` (scalar global) and `constExprValue` (array element / struct > field / nested aggregate). A non-enum destination or an unknown variant is > diagnosed loudly — never silently zero-initialized. The compiler-injected > `OS`/`ARCH` globals now serialize to their real `.unknown` tag (6 / 4) instead > of relying on the null→zero fallback; runtime reads are unchanged because they > resolve through `comptime_constants`. As part of the same exhaustiveness pass, > the silent `func_ref => … orelse LLVMConstNull` fallbacks in the LLVM constant > emitters (`src/ir/emit_llvm.zig`) were removed: 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 enum > global, global array of enum, enum struct field, explicit-value `enum u16` for > element-stride, struct-array with enum field) — FAILS on the pre-fix compiler > (wrong tag / rejected as non-constant), PASSES after. Negative: > `examples/1127-diagnostics-global-enum-literal-bad-variant.sx` (unknown variant > rejected loudly, exit 1). ## Symptom A module-global enum initialized with a non-zero enum literal silently reads back as the zero tag. Observed: `chosen : Color = .green;` prints `.red` and the program exits 1. Expected: it should print `.green` and exit 0, or the compiler should reject unsupported enum-literal global initializers loudly instead of zero-initializing. ## Reproduction ```sx #import "modules/std.sx"; Color :: enum u8 { red; green; blue; } chosen : Color = .green; main :: () -> s32 { print("chosen={}\n", chosen); if chosen == .green { print("PASS\n"); return 0; } print("FAIL\n"); return 1; } ``` Observed: ```text chosen=.red FAIL ``` Expected: ```text chosen=.green PASS ``` ## Investigation prompt Fix issue 0082: module-global enum literal initializers silently become the zero tag. Suspected area: - `src/ir/lower.zig`, `Lowering.globalInitValue`: the `.enum_literal => null` carve-out preserves the stdlib's historical zero-init path for compiler- injected `OS : OperatingSystem = .unknown`, but it also silently drops any user-written non-zero enum literal such as `.green`. - `src/ir/lower.zig`, `Lowering.constExprValue`: aggregate enum-literal fields are currently not serialized either, so audit both top-level and aggregate enum literals. Likely fix: - Resolve the destination enum type from `var_ty` / `expected_ty` and serialize the enum tag as a `ConstantValue.int` with the variant index/value. - If a particular enum literal shape cannot be serialized yet (payload variants, unsupported explicit tag values, etc.), emit a diagnostic instead of returning `null`. - Preserve the compiler-injected `OperatingSystem` / `Architecture` behavior by making those globals real constants, not by relying on null initializer fallback. Verification: - Run the repro above and expect `chosen=.green` / `PASS` / exit 0. - Add a pinned regression in the `01xx` types block for a non-zero enum global and, if supported by the fix, an enum field inside a global aggregate. - Run: ```sh zig build zig build test bash tests/run_examples.sh ```