A typed module-level constant whose initializer did not match its annotation was silently accepted: `N : string : 4` compiled, then `print(N)` segfaulted (an integer emitted as a `string` const → a bogus pointer) and `[N]s64` folded `N` to 4 as an integer count. Issue 0088. Root cause: `registerTypedModuleConst` stored the annotation type but never validated the initializer literal against it, and `program_index.moduleConstInt` folded a const into a count by inspecting the initializer node alone, ignoring `ModuleConstInfo.ty`. Fix at the declaration (kills both symptoms): - lower.zig: `registerTypedModuleConst` now validates the initializer via `typedConstInitFits` (arms mirror `emitModuleConst`'s faithful-emit precondition: int→int/float, float→float, bool→bool, string→string, null→pointer/optional, `---`→any). A mismatch emits a `type mismatch` diagnostic at the initializer span and does not register the const (also evicting the pass-0 placeholder). Not routed through `coercionResolver().classify`: that runtime-coercion planner is unsound here (null's natural type is void → false-rejects `*T`; bool is 1 bit → false-accepts s64). - program_index.zig: `moduleConstInt` now takes the `TypeTable` and gates the fold on `isCountableConstType(ci.ty)` (integer of any width, or a float), so a non-numeric typed const can never fold into a count off its initializer node. Callers in lower.zig and type_bridge.zig updated. Regression: - examples/1143-diagnostics-typed-module-const-mismatch.sx (negative, exit 1) - examples/0162-types-typed-module-const-roundtrip.sx (positive) - program_index.test.zig: gate-on-declared-type unit test Docs: specs.md §3 Constant Binding + readme.md note the compatibility rule.
36 lines
1.2 KiB
Plaintext
36 lines
1.2 KiB
Plaintext
// Valid typed module-level constants compile, fold, and print correctly across
|
|
// every initializer/annotation pairing the registrar accepts:
|
|
// - integer → integer (`K : s64 : 4`) — usable as an array count too
|
|
// - integer → float (`W : f32 : 800`)
|
|
// - float → float (`PI : f32 : 3.14159`)
|
|
// - string → string (`S : string : "hi"`)
|
|
// - null → pointer (`P : *void : null`)
|
|
//
|
|
// Companion to the negative example 1143: the issue-0088 fix rejects a typed
|
|
// const whose initializer mismatches its annotation, and these correctly-typed
|
|
// consts must keep working (no over-rejection).
|
|
#import "modules/std.sx";
|
|
|
|
K : s64 : 4;
|
|
W : f32 : 800;
|
|
PI : f32 : 3.14159;
|
|
S : string : "hi";
|
|
P : *void : null;
|
|
|
|
main :: () {
|
|
// Integer const: prints AND drives an array dimension (len 4).
|
|
a : [K]s64 = ---;
|
|
a[0] = 10;
|
|
a[3] = 40;
|
|
print("K={} len={} a0={} a3={}\n", K, a.len, a[0], a[3]);
|
|
|
|
// Integer-into-float and float consts print as floats.
|
|
print("W={} PI={}\n", W, PI);
|
|
|
|
// String const prints its text.
|
|
print("S={}\n", S);
|
|
|
|
// Null pointer const is null.
|
|
print("P_is_null={}\n", P == null);
|
|
}
|