Skip to content

gen-c: lower a tuple in every position, not only in a return - #3456

Merged
gHashTag merged 1 commit into
masterfrom
parity/cross-product
Sep 8, 2026
Merged

gen-c: lower a tuple in every position, not only in a return#3456
gHashTag merged 1 commit into
masterfrom
parity/cross-product

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 8, 2026

Copy link
Copy Markdown
Owner

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'

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 cc rather than matching on the type name, for
exactly that reason.

Population: zero, and measured

before after
generated C files changed 0
errors (-ferror-limit=0) 15126 15126
files that compile 301 301

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.

mutant dead tests
use sites stop naming the struct 2
collection reverted (name without definition) 2
locals dropped from the collection 0 → 1 after the local-only test

Full suite: 2625 passed, 0 failed.

The round

Fifth round of tools/backend_parity_table.py — the cross product of
combinations 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 []*i32 reaches C
as *i32* x in every position.

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
gHashTag enabled auto-merge (squash) September 8, 2026 03:03
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-08 03:03:42 UTC

Summary

Status Count
Total Open PRs 16
PRs with Failing Checks 13
PRs with All Checks Green 3
READY 2
FAILING 13
PENDING 0
NO CHECKS YET 0

These columns do not partition: 2 + 13 + 0 + 0 = 15, and there are 16 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=92f44987b4d6 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit 393030d into master Sep 8, 2026
29 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gen-c: a tuple is only lowered in return position

1 participant