You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gen-c uses Trit 141 times and declares it zero times: the C backend does not follow "use" #2764
t27c corpus puts C last of the four backends — 157 of 559 accepted (24.2%), against Zig 217, rustc 214 and Verilog 378. The largest systematic cause is not a long tail.
The measurement
specs/vsa/ops.t27 opens with
use base::types;
use base::ops;
and Trit is declared in specs/base/types.t27. The generated C:
141 uses, zero declarations. The prelude emits only <stdint.h> <stdbool.h> <stddef.h> <assert.h> and nothing from the imported spec. cc reports unknown type name 'Trit' in 12 specs measured across the whole corpus.
What this is not
It is not a missing typedef Trit in the prelude. Trit is not a language built-in — it is declared in a spec, and other specs import it. Adding a typedef would paper over the actual gap and invent a representation the language never fixed.
The gap is that gen-c does not resolve use: it emits a standalone translation unit per spec and never emits, includes, or forward-declares anything the spec imported.
Rust has the same shape, C just fails louder
gen-rust on the same spec emits pub fn bind(a: Vec<Trit>, …) with no Trit in scope either. Zig drops the affected code entirely, so its number does not show the cost. Three backends, three different silences over one missing mechanism.
Why this is worth doing
Every other lever in the Rust column has now been pulled — the ruler (-o /dev/null, #2760), unconditional serde derives (#2760), and Vec<const T> — taking it from a false 0 to 214. C has had none of that, and this is the one cause that is systematic rather than per-spec: the first-error histogram is otherwise a long tail of user types appearing once each.
Effort is days, not minutes: it needs a decision about what an imported declaration becomes in C — a generated header per spec plus #include, or inlined declarations in dependency order — and the same decision then applies to Rust.
changed the title [-]gen-c uses Trit 141 times and declares it zero times: the C backend does not follow [/-][+]gen-c uses Trit 141 times and declares it zero times: the C backend does not follow "use"[/+]on Aug 28, 2026
The diagnosis in this issue is wrong, and I wrote it.
The gap is that gen-c does not resolve use
It does. run_gen_c calls use_resolve::resolve, and so do the Zig and Rust backends. The resolution runs on all three and refuses, for a reason it states and then discards.
Trit is declared verbatim identically in specs/base/types.t27 and specs/base/ops.t27. Six specs import both, so the name has two candidates, and use_resolve declines to pick one — writing
// UNRESOLVED Trit: declared in base/ops.t27 and base/types.t27 -- ambiguous, not spliced
into the resolved source. Codegen strips comments, so that sentence never reaches the generated file. The measurement in this issue — 141 uses, 0 declarations — is correct; the cause attached to it was not.
Two things follow, and they are now separate:
Two identical declarations are not ambiguous #2829 — splice when every candidate says the same thing. 30 ambiguous (spec, name) pairs corpus-wide, 10 agree, 20 genuinely differ and stay refused. unknown type name errors across the 460 specs that import something fall 944 → 802; specs compiling with zero errors stay 82 → 82, so no spec flipped.
Also corrected here: this issue's premise that specs/vsa/ops.t27 "opens with" its use lines. They are indented inside module VSAOps {, which is why grep '^use ' reports 68 specs when 460 import something.
Leaving this open for the part neither PR addresses: the refusal is invisible to the person reading the error.cc says unknown type name 'Trit', and the compiler's own explanation exists, in a comment, in an intermediate nobody sees. Carrying an UNRESOLVED diagnostic to stderr or into the generated file as a target-language comment is the remaining work.
A boundary drafted from the paths this issue already names, so a bee can take it. Nothing is reserved until this is in the issue body - the Queen reads the body, not comments. Check the paths first: a wrong boundary reserves files the work does not own.
An attempt claimed this issue on 2026-09-24 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.
Activity
[-]gen-c uses Trit 141 times and declares it zero times: the C backend does not follow [/-][+]gen-c uses Trit 141 times and declares it zero times: the C backend does not follow "use"[/+]gHashTag commentedon Aug 29, 2026
The diagnosis in this issue is wrong, and I wrote it.
It does.
run_gen_ccallsuse_resolve::resolve, and so do the Zig and Rust backends. The resolution runs on all three and refuses, for a reason it states and then discards.Tritis declared verbatim identically inspecs/base/types.t27andspecs/base/ops.t27. Six specs import both, so the name has two candidates, anduse_resolvedeclines to pick one — writinginto the resolved source. Codegen strips comments, so that sentence never reaches the generated file. The measurement in this issue — 141 uses, 0 declarations — is correct; the cause attached to it was not.
Two things follow, and they are now separate:
unknown type nameerrors across the 460 specs that import something fall 944 → 802; specs compiling with zero errors stay 82 → 82, so no spec flipped.varbecomestypedef <initializer> <name>;. This is whyhslm.t27was the one spec of six whoseTriterrors did not improve.Also corrected here: this issue's premise that
specs/vsa/ops.t27"opens with" itsuselines. They are indented insidemodule VSAOps {, which is whygrep '^use 'reports 68 specs when 460 import something.Leaving this open for the part neither PR addresses: the refusal is invisible to the person reading the error.
ccsaysunknown type name 'Trit', and the compiler's own explanation exists, in a comment, in an intermediate nobody sees. Carrying an UNRESOLVED diagnostic to stderr or into the generated file as a target-language comment is the remaining work.use_resolve: two identical declarations are not ambiguous (#2829)
skill(ci-gates) 240-242: the issue, the guard's precondition, the sil…
gen: say what `use` could not resolve, and when the splice was dropped (
use_resolve: an alias is not a second opinion, and a comment is not a…
gHashTag commentedon Sep 23, 2026
A boundary drafted from the paths this issue already names, so a bee can take it. Nothing is reserved until this is in the issue body - the Queen reads the body, not comments. Check the paths first: a wrong boundary reserves files the work does not own.
Boundary
specs/base/types.t27specs/vsa/ops.t27github-actions commentedon Sep 30, 2026
Re-filed as #5278.
An attempt claimed this issue on 2026-09-24 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.