Repository navigation
gen-c: a numeric a ** b is lowered as an array repeat, /* repeat: a ** b */ {0} #7427
Description
Part of #5980 (self-host P1: the core must refuse what gen-c gets wrong, so gen-c should stop getting it wrong).
What happens
t27c gen-c treats every ** as the array repeat operator. A numeric power is written as a comment and an empty initializer, and gen-c exits 0:
module m;
fn p(a: u32, b: u32) -> u32 { return a ** b; }
fn q(x: f64) -> f64 { return x ** 2.0; }
return /* repeat: a ** b */ {0};
cc rejects return {0}; in a scalar function, so these functions never compile. The language's own compiler specs define ** on numbers as the power operator: specs/compiler/typechecker.t27 lists it in is_arithmetic_op, and specs/compiler/optimizer.t27 folds 2 ** 10 to 1024 in eval_binary_const. Two corpus specs use it: specs/provider/adapters.t27:357 and specs/portable/relay_observer.t27:198.
Expected
A ** whose left operand is not an array literal is a numeric power. gen-c writes it as a call that C can compile: pow/powf/powl for a float operand and an exact integer power for an integer operand. The array repeat [_]T{v} ** n keeps its current lowering.
Check
cargo build --release -p t27c
printf 'module m;\nfn p(a: u32, b: u32) -> u32 { return a ** b; }\ntest t { assert(p(2, 10) == 1024); assert(p(3, 0) == 1); }\n' > /tmp/p.t27
./target/release/t27c gen-c /tmp/p.t27 > /tmp/p.c && cc -std=gnu11 -DT27_TEST_MAIN /tmp/p.c -o /tmp/p -lm && /tmp/p
Today the cc step fails. After the fix the test passes. The regression test is bootstrap/tests/genc_nested_repeat.rs, shared with #7353 because both defects are in the same ** lowering.
Boundary
specs/compiler/optimizer.t27specs/compiler/typechecker.t27specs/portable/relay_observer.t27specs/provider/adapters.t27bootstrap/tests/genc_nested_repeat.rs
User Scenarios
- Given a T27 module with a function returning
a ** bwhere both operands are integer scalars, whent27c gen-ccompiles it, then the generated C uses an integer power implementation (not an array repeat) and the resulting binary passesassert(p(2, 10) == 1024). - Given a T27 module with a function returning
x ** 2.0where the left operand is a float scalar, whent27c gen-ccompiles it, then the generated C callspow/powf/powland the resulting binary executes without compile errors.
Requirements
- FR-001: The gen-c lowering MUST distinguish numeric
**from array repeat by inspecting whether the left operand is an array literal. - FR-002: For integer operands, gen-c MUST emit an exact integer power computation (e.g., loop or builtin) that evaluates at runtime without linking
-lm. - FR-003: For floating-point operands, gen-c MUST emit a call to
pow,powf, orpowlmatching the operand width and link with-lm. - FR-004: The array repeat form
[_]T{v} ** nMUST continue to lower to the current repeat initializer. - FR-005: The typechecker and optimizer specs MUST continue to treat
**as an arithmetic operator on numbers (no spec change required).
Success Criteria
cargo build --release -p t27cexits 0printf 'module m;\nfn p(a: u32, b: u32) -> u32 { return a ** b; }\ntest t { assert(p(2, 10) == 1024); assert(p(3, 0) == 1); }\n' > /tmp/p.t27 && ./target/release/t27c gen-c /tmp/p.t27 > /tmp/p.c && cc -std=gnu11 -DT27_TEST_MAIN /tmp/p.c -o /tmp/p -lm && /tmp/pexits 0printf 'module m;\nfn q(x: f64) -> f64 { return x ** 2.0; }\ntest t { assert(q(3.0) == 9.0); }\n' > /tmp/q.t27 && ./target/release/t27c gen-c /tmp/q.t27 > /tmp/q.c && cc -std=gnu11 -DT27_TEST_MAIN /tmp/q.c -o /tmp/q -lm && /tmp/qexits 0cargo test --test genc_nested_repeatexits 0 (5 tests)
Activity
gHashTag commentedon Oct 7, 2026
A fix is on branch
genc-repeat-pow(head db2c58f), but no PR is open because it is over the foreign-line budget (#7371). On top of #7406 it adds compiler.rs +292 and tests +304, against limits of 40 per file and 80 per PR, and #7406 is parked for the same reason.What the branch does:
**repeat is written as one comment, with the rows kept.a ** bbecomest27_pow/t27_ipow.On the t27c lab, 11/11 tests pass with the fix and 10/11 fail with it reverted.
The corpus diff on the previous head showed 16 specs change C, about 11 of them sealed. The branch is not resealed yet. Landing it needs the lowering written in .t27 or an owner decision.
gHashTag commentedon Oct 7, 2026
Reopened 2026-10-07: the bulk close of issues without a
## Boundarysection was reverted by the owner. Nothing to do here; this comment replaces the earlier close notice.t27core: local arrays, separators in dimensions, numeric ** refused (C…
github-actions commentedon Oct 17, 2026
Re-filed as #9885.
An attempt claimed this issue on 2026-10-08 and left an empty branch. A dispatch row that has spent its retry ceiling is released once and then keeps its issue for good, which is the right rule for a third identical failure and the wrong outcome for an issue nobody ever attempted twice. The new issue carries the same work, the same boundary, and today's brief.
Closing this one so the swarm can take the work again.