Repository navigation
self-host: gen-c drops the value of a global [_]T{v} ** N repeat #6050
Description
Profile (read first)
You are working as Gamma (Compiler Core) on epic #5980: rewrite t27c in t27 itself.
The self-hosted core (specs/compiler/core/t27core.t27, PR #6041) must write exactly the
bytes t27c gen-c writes, so every gen-c defect is a defect the core has to refuse instead of
learn. Fixing it here is what lets the core grow. Rules for this task:
- Change the Rust emitter only inside the Boundary below.
gen/is generated: never hand-edit it. - Build with
cargo build --release -p t27cand use./target/release/t27cfrom the repository
root, not at27con PATH. - Write the regression test first and watch it fail on the unfixed compiler. Then fix, and
revert the fix once to watch the test go red again. Say in the PR that you did both. - Any other spec whose generated C changes must be listed in the PR by path, with one line on
why the new bytes are right. A silent corpus change is a failed task. - The PR body says
Closes #plus this issue's number andPart of #5980. ASCII only in source files.
Context
A global array initialised with [_]u8{5} ** 4 is emitted as /* repeat: { 5 } ** 4 */ {0}: the repeated value is lost and the array is all zeros. #6038 fixed the typed [T; N] local and return forms; this is the global [N]T form, still wrong on master. The self-hosted core refuses any repeat value other than 0 (E_ARRAY).
Reproduce
cargo build --release -p t27c
printf 'module m;\nconst N: i64 = 4;\nvar r: [N]u8 = [_]u8{7} ** N;\nvar a: [4]u8 = [_]u8{5} ** 4;\n' > /tmp/rep.t27
./target/release/t27c gen-c /tmp/rep.t27
Today the relevant output is:
static uint8_t r[N] = /* repeat: { 7 } ** N */ {0};
static uint8_t a[4] = /* repeat: { 5 } ** 4 */ {0};
Original checks (kept for history; the Queen does not run these)
-
./target/release/t27c gen-c /tmp/rep.t27 > /tmp/rep.c && printf '#include "rep.c"\nint main(void){return (a[0]==5 && a[3]==5 && r[0]==7 && r[3]==7)?0:1;}\n' > /tmp/repm.c && cc -w -o /tmp/repm /tmp/repm.c && /tmp/repm; echo $?prints0(today1)
-
- the same program builds and passes with
gcctoo if it is installed; say in the PR which compilers you ran
- the same program builds and passes with
-
cargo test --release -p t27c --test genc_global_repeatpasses
Original file list
bootstrap/src/compiler.rsbootstrap/tests/genc_global_repeat.rs
Original scenarios
- Given
/tmp/rep.t27written by the Reproduce block,
when./target/release/t27c gen-c /tmp/rep.t27runs and its output is compiled withcc,
then every element ofais 5 and every element ofris 7, for a literal count and for a const count.
Original requirements
- FR-001: the repeated value MUST reach every element;
{0}is right only when the value is 0. - FR-002: do not change the
[T; N]paths fix(c): initialize typed repeat arrays inside their value wrapper #6038 just fixed. - FR-900:
cargo test --release -p t27c --test genc_global_repeatMUST pass, and MUST fail with the fix reverted. - FR-901: if
bootstrap/tests/core_selfhost.rsexists on your base,cargo test --release -p t27c --test core_selfhostMUST still pass.
Queen-runnable restatement (2026-10-05)
This block restates the issue so the Queen's runner reads one boundary and one list of checks; the text above is kept for history and its own file list and checks are superseded by the sections below.
The bee branch queen-6050 carries bootstrap/tests/genc_global_repeat.rs (63 lines of hand-written Rust test), which cannot land under only-t27. On master t27c gen-c still emits static uint8_t a[4] = /* repeat: { 5 } ** 4 */ {0}; for a global array repeat, so the bug is live. The t27 part is a rule spec in the shape of specs/compiler/zig_test_shadowing.t27: it pins the construct with tests that run today through the Zig backend, and its comments state what the C backend must emit, so the Rust fix (owner-approved, separately) has an executable target. Globals must not be named a or r: the generated Zig reports a parameter shadowing them.
Boundary
specs/compiler/c_global_repeat.t27
User Scenarios & Testing
- Given a module-level array initialised with
[_]u8{5} ** 4and with[_]u8{7} ** N(N a const), when the rule spec reads the elements back, then every element equals the repeated value, and the spec's comments name the C output each global must get ({5, 5, 5, 5}, not{0}).
Requirements
- FR-001:
specs/compiler/c_global_repeat.t27MUST declare a global array initialised by a literal-count repeat and one initialised by a const-count repeat, and test first and last element of each. - FR-002: Its
//comments MUST cite self-host: gen-c drops the value of a global[_]T{v} ** Nrepeat #6050 and state the C initialiser the backend must emit for each global. - FR-003: The change MUST NOT add or modify non-t27 hand-written code (specs/policy/own_language.t27).
Success Criteria
test -f specs/compiler/c_global_repeat.t27 && echo presentprintspresent(today the file does not exist)grep -cE '\{[0-9]+\} \*\* ' specs/compiler/c_global_repeat.t27prints at least2- both repeat forms are presentgrep -c '6050' specs/compiler/c_global_repeat.t27prints at least1t27c test-report specs/compiler/c_global_repeat.t27 2>&1 | grep -cE '^ FAIL +0$'prints1- the generated code compiles and every test passest27c test-report specs/compiler/c_global_repeat.t27 2>&1 | grep -E '^ tests ' | tr -dc 0-9prints at least2- the count of tests that ran
Activity
gHashTag commentedon Oct 5, 2026
Branch queen-6050 carries bootstrap/tests/genc_global_repeat.rs, hand-written Rust, which cannot land under only-t27 (specs/policy/own_language.t27). A t27 version is a rule spec, specs/compiler/c_global_repeat.t27, that pins literal-count and const-count global repeats with tests and states the C initialiser each must get; the Rust emitter fix itself needs the owner-approved-foreign label. The issue was restated to that spec, and the branch is not deleted.
fix(gen-c): a global `** N` repeat keeps its value instead of zeros (C…
chore(seals): reseal specs whose gen-c output changed (Refs #6050 #6051
fix(gen-c): a global `** N` repeat keeps its value instead of zeros (C…
chore(seals): reseal specs whose gen-c output changed (Refs #6050 #6051
fix(gen-c): a global `** N` repeat keeps its value instead of zeros (C…
chore(seals): reseal specs whose gen-c output changed (Refs #6050 #6051