gen-c: lower a tuple in every position, not only in a return - #3456
Merged
Conversation
Closes #3455 The `t27_tuple_*` hoisted struct existed and `c_return_type_r` was its only caller, so a tuple anywhere else reached C as the t27 text: int32_t probe(H h, (u8, i32) t); struct H { (u8, i32) f; }; (u8, i32) x; BOTH HALVES WERE MISSING AND ONLY ONE WAS OBVIOUS. Teaching the use sites to name the struct, without also teaching the typedef collection to emit it, produces error: unknown type name 't27_tuple_uint8_t_int32_t' which is WORSE than the t27 text, because it looks right. That was the first attempt. The collection considered a function's return type and a destructured call's return type; parameters, struct fields and locals were absent from it, and both ends are fixed here. Every test hands the header to `cc` rather than matching on the type name, for exactly that reason. POPULATION ZERO, measured rather than asserted: no spec puts a tuple in these positions today, and the change alters NOT ONE generated file across 651 specs -- 15126 errors and 301 compiling files, before and after. Stated plainly; its value is that the next spec to write one gets C. A MUTANT SURVIVED because one fixture covered three positions at once. Dropping locals from the collection changed nothing any test caught: the fixture used a single tuple type as a parameter, a field AND a local, so the typedef was still collected from the other two. Each position needs its subject alone in it. The added test uses a tuple appearing only as a local, and the mutant dies. Three mutants, three dead. Two further defects from the same round are filed rather than fixed, both population zero: a tuple whose element is a fixed array gives `uint8_t* f0` -- the #3446 defect inside a tuple struct -- and `[]*i32` reaches C as `*i32* x`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
September 8, 2026 03:03
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3455
The
t27_tuple_*hoisted struct existed andc_return_type_rwas its onlycaller, so a tuple anywhere else reached C as the t27 text:
Both halves were missing, and only one was obvious
Teaching the use sites to name the struct, without also teaching the
typedef collection to emit it, produces:
— worse than the t27 text, because it looks right. That was my first attempt.
The collection considered a return type and a destructured call's return type;
parameters, struct fields and locals were absent from it.
Every test hands the header to
ccrather than matching on the type name, forexactly that reason.
Population: zero, and measured
-ferror-limit=0)No spec puts a tuple in these positions today. Said up front; the value is that
the next spec to write one gets C rather than a header that does not parse.
A mutant survived because one fixture covered three positions
Dropping locals from the collection changed nothing any test caught: the
fixture used one tuple type as a parameter, a field and a local, so the
typedef was still collected from the other two. Each position needs its subject
alone in it.
Full suite: 2625 passed, 0 failed.
The round
Fifth round of
tools/backend_parity_table.py— the cross product ofcombinations against all four positions. Every finding was latent: three
real defects, all population zero. Closest to a dry round so far, and not one;
the stopping rule wants two consecutive rounds finding nothing.
The other two are filed in #3455: a tuple whose element is a fixed array gives
uint8_t* f0(the #3446 defect inside a tuple struct), and[]*i32reaches Cas
*i32* xin every position.