fix(ir): reject typed module const whose initializer mismatches annotation [F0.7]
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.
This commit is contained in:
7
specs.md
7
specs.md
@@ -1458,6 +1458,13 @@ SOME_FUNC :: () => 42; // () -> s32
|
||||
SOME_TYPE :: f64; // type alias
|
||||
```
|
||||
|
||||
With an explicit annotation, the initializer literal must be compatible with the
|
||||
annotated type, or the declaration is a compile-time `type mismatch` error: an
|
||||
integer literal fits any integer or float type (`W : f32 : 800`), a float literal
|
||||
a float type, a boolean `bool`, a string literal `string`, `null` a pointer or
|
||||
optional, and `---` any type. A mismatch such as `N : string : 4` is rejected at
|
||||
the declaration — it does not register a usable constant.
|
||||
|
||||
### Variable Binding (mutable)
|
||||
|
||||
```sx
|
||||
|
||||
Reference in New Issue
Block a user