fix(ir): validate const-expression typed module-const initializers [F0.7]
Attempt 1 rejected only LITERAL initializers that mismatch a typed module
const's annotation; a const-EXPRESSION initializer escaped, so the same
issue-0088 root remained for `M :: 2; N : string : M + 2` — accepted at exit 0,
folding `[N]s64` to 4 and printing N as an integer.
Root cause: `registerTypedModuleConst` validated only the enumerated literal
node kinds; any other kind fell through to `else => {}`, and pass 0
pre-registers binary_op/unary_op consts as a `.s64` placeholder that was never
reconciled with the annotation.
Fix — validate by TYPE, not by node kind:
- lower.zig: `registerTypedModuleConst` now covers literals AND const-expressions
(binary_op/unary_op) through one path. `typedConstInitFits` keeps the literal
arms and routes any non-literal through the new `constExprInitFits`, which
compares the initializer's INFERRED type (`inferExprType`, the existing
type-inference facility — no second const evaluator) to the annotation with the
same integer/float compatibility. A mismatch emits the `type mismatch` diagnostic
(a const-expression is described by its inferred type, e.g. "an integer
expression") and evicts the pass-0 placeholder; a match registers the const at
its resolved annotation type (the same `put` the literal path always did), so a
const-expression folds and emits at its declared type.
- `literalKindName` → `initializerDescription` (+ `constExprDescription`) so the
message is accurate for both a literal and a const-expression initializer.
Regression:
- examples/1143: extended with `E : string : M + 2` and `V : string : -M`
(const-expr mismatches → exit 1, pinned diagnostics).
- examples/0162: extended with `KE : s64 : M + 2` (used as a count + printed) and
`WE : f32 : M + 2` (over-rejection guard — valid const-exprs still work).
- program_index.test.zig: count-gate test extended with a binary_op value node
declared `string` (must not fold as a count).
Docs: specs.md §3 + readme.md generalized from "initializer literal" to cover
constant expressions; issues/0088 RESOLVED banner updated.
This commit is contained in:
@@ -2,3 +2,4 @@ K=4 len=4 a0=10 a3=40
|
||||
W=800.000000 PI=3.141590
|
||||
S=hi
|
||||
P_is_null=true
|
||||
KE=4 len=4 WE=4.000000
|
||||
|
||||
@@ -1,23 +1,35 @@
|
||||
error: type mismatch: constant 'N' is declared 'string' but its initializer is an integer literal
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:13:14
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:18:14
|
||||
|
|
||||
13 | N : string : 4; // integer literal where a string is annotated
|
||||
18 | N : string : 4; // integer literal where a string is annotated
|
||||
| ^
|
||||
|
||||
error: type mismatch: constant 'F' is declared 's64' but its initializer is a string literal
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:14:14
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:19:14
|
||||
|
|
||||
14 | F : s64 : "x"; // string literal where an integer is annotated
|
||||
19 | F : s64 : "x"; // string literal where an integer is annotated
|
||||
| ^^^
|
||||
|
||||
error: type mismatch: constant 'B' is declared 's64' but its initializer is a boolean literal
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:15:14
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:20:14
|
||||
|
|
||||
15 | B : s64 : true; // boolean literal where an integer is annotated
|
||||
20 | B : s64 : true; // boolean literal where an integer is annotated
|
||||
| ^^^^
|
||||
|
||||
error: type mismatch: constant 'G' is declared 's64' but its initializer is a float literal
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:16:14
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:21:14
|
||||
|
|
||||
16 | G : s64 : 1.5; // float literal where an integer is annotated
|
||||
21 | G : s64 : 1.5; // float literal where an integer is annotated
|
||||
| ^^^
|
||||
|
||||
error: type mismatch: constant 'E' is declared 'string' but its initializer is an integer expression
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:22:14
|
||||
|
|
||||
22 | E : string : M + 2; // integer EXPRESSION where a string is annotated
|
||||
| ^^^^^
|
||||
|
||||
error: type mismatch: constant 'V' is declared 'string' but its initializer is an integer expression
|
||||
--> examples/1143-diagnostics-typed-module-const-mismatch.sx:23:14
|
||||
|
|
||||
23 | V : string : -M; // integer (unary) expression where a string is annotated
|
||||
| ^^
|
||||
|
||||
Reference in New Issue
Block a user