// issue-0020: Global `Foo = .{}` zero-initializes, ignoring field defaults // // Struct field defaults declared via `field: T = expr;` are honored when the // struct is constructed at function-local scope, but are silently dropped // when the struct is declared at module scope with `= .{}`. // // Repro: // // Foo :: struct { // running: bool = true; // default // } // // g_foo : Foo = .{}; // global → g_foo.running == false (BUG) // // main :: () { // l_foo : Foo = .{}; // local → l_foo.running == true (correct) // } // // Surface bites: // // - In the SX Chess game, the SDL3 platform backend stores a `running: bool // = true` field on `SdlPlatform`. With `g_plat : SdlPlatform = .{};` the // main loop's `while self.running { ... }` exits immediately because // `running` was zero-initialized despite the field default. // - Workaround: assign defaults explicitly in the type's `init` method, or // spell every field out at the global construction site: // g_plat : SdlPlatform = .{ running = true }; // // Likely cause: the globals path emits an LLVM ConstantAggregateZero (or // memset-to-zero) for the initializer, skipping the per-field default-expr // lowering used for local declarations. // // This file is a runnable repro: locals print "running=true", globals print // "running=false". #import "modules/std.sx"; Foo :: struct { running: bool = true; x: s32 = 42; } g_foo : Foo = .{}; main :: () -> void { out("global running="); out(if g_foo.running then "true" else "false"); out("\n"); l_foo : Foo = .{}; out("local running="); out(if l_foo.running then "true" else "false"); out("\n"); }