attempt-3 made the value-const READ source-aware (own-wins / ambiguous) but
the dimension/count fold of a SELECTED const's RHS still recursed through the
global last-wins `module_const_map`, so a nested same-name leaf came from the
wrong module. Reviewer R1: a.sx `M::1; K::M+1`, b.sx `M::10; K::M+1`, with both
`[K]u8` (a_len) and `return K` (a_val) — pre-fix `a_len=11 a_val=2`, an
INCOHERENCE for the same const `K` (a_val read A's chain; a_len read B's `M`).
`comptimeIntNamed` delegated to `moduleConstIntWith(global_map, ...)`, whose
leaf ctx (`ModuleConstCtx`) resolved nested names through the global map. The
value path (`emitModuleConst` -> `foldCountI64(ci.value, self)`) folds through
`self`, so its leaves bounce back to the source-aware `comptimeIntNamed` — which
is why a_val was already correct.
- New `SourceConstCtx` (lower.zig): the leaf-resolution twin of `ModuleConstCtx`,
but every nested const leaf re-selects its OWN source author via
`selectModuleConst` (own-wins / ambiguous), never the global last-wins map.
`ConstFoldFrame` cycle-guards a const whose RHS references another const.
- `comptimeIntNamed` / `lookupFloatName` / `nameIsFloatTyped` now fold the
selected `ci`'s RHS through `SourceConstCtx` (via `foldSourceConstInt` /
`foldSourceConstFloat` / `sourceConstIsFloatTyped`). This makes the dimension
and value reads of a shadowed expression-chain const coherent.
- Drop the now-unused `moduleConst{Int,Float,IsFloatTyped}With` wrappers from
program_index.zig; expose `isCountableConstType` / `isFloatConstType`.
Single-author -> byte-identical (the selected `ci` IS the global one and every
nested leaf has one author). The stateless `type_bridge` registration-time const
reader still folds leaves through the global map, but realistic dim sites (struct
fields, array aliases — probed) resolve via the stateful path and stay coherent
under import-order swaps; no reachable wrong-dimension found (tracked follow-up,
byte-identical single-author).
Regression: examples/0761-modules-same-name-const-expr-chain-dim — a_len=2
a_val=2, b_len=11 b_val=11. Fail-before on 72f06a1 (`a_len=11`), pass-after.
Gate: zig build + zig build test (423/423, LSP sweep 515 clean) + run_examples
(499/0, 498 prior byte-identical + 0761) + m3te ios-sim build exit 0.
20 lines
1.0 KiB
Plaintext
20 lines
1.0 KiB
Plaintext
// issue 0105 / F2 — same-name const EXPRESSION CHAIN, coherent across a value
|
|
// read AND an array dimension. Two flat-imported modules each declare a same-name
|
|
// `M` and a same-name `K :: M + 1` that reads `M`. Each module uses ITS OWN `K`
|
|
// both as a runtime value (`return K`) and as an array dimension (`[K]u8`).
|
|
//
|
|
// The fold of a SELECTED const's RHS must resolve nested same-name leaves (the
|
|
// `M` inside `K :: M + 1`) in the SELECTED author's source context, not through
|
|
// the global last-wins `module_const_map`. Pre-fix (72f06a1) the dimension fold
|
|
// recursed through the global map, so `a_len` read B's `M` (= 11) while `a_val`
|
|
// correctly read A's chain (= 2) — an INCOHERENCE for the same const `K`. Now
|
|
// both observables agree per module: a_len=2 a_val=2, b_len=11 b_val=11.
|
|
#import "modules/std.sx";
|
|
#import "0761-modules-same-name-const-expr-chain-dim/a.sx";
|
|
#import "0761-modules-same-name-const-expr-chain-dim/b.sx";
|
|
|
|
main :: () -> s32 {
|
|
print("a_len={} a_val={} b_len={} b_val={}\n", a_len(), a_val(), b_len(), b_val());
|
|
0
|
|
}
|