Skip to content

gen-c: a negative element makes a literal list signed - #3463

Merged
gHashTag merged 1 commit into
masterfrom
c/remaining-auto-type
Sep 8, 2026
Merged

gen-c: a negative element makes a literal list signed#3463
gHashTag merged 1 commit into
masterfrom
c/remaining-auto-type

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Refs #3459

670 __auto_type x = { … } errors remained and had never been
categorised
. Printing them by shape before writing any code split the wall
into six families:

count shape
319 { 0 } an empty list
~92 { cast_iN(N), … } calls
~85 { N, -N, … } a negative element
32 { N.NeN } exponent suffix
21 { Trit.pos, … } enum member access
12 { "s", "s" } strings

The largest family cannot be inferred at all

{ 0 } comes from var x = []439 such sites in the specs. C11 has no
{}, so { 0 } is the emitter's stand-in, and an empty list has nothing to
take a type from. Naming one would be inventing it; a test now pins that it
keeps __auto_type.

Finding this out is why the measurement came first.

The tractable family: negatives

A negative element is a unary expression, not a literal, so the whole list
was refused — 193 corpus sites. Looking through the - was the easy half. The
first version then emitted:

uint32_t x[2] = { 1, -1 };

an unsigned type holding a negative — exactly the quiet wrong answer this
class of repairs exists to avoid. A negative now makes the list i32.

Measured — -ferror-limit=0

before after
errors 14165 14041
__auto_type with initializer list 670 523
files better 11

Two worse, both unmasking. Sign diagnostics unchanged — 7 -Wsign-compare
and 60 conversions on both sides — so the signed choice introduced none.
Across three passes: 1729 → 523.

Only - is looked through

[!1] keeps __auto_type: a unary whose value is not the literal underneath
would type the list from the wrong number.

mutant dead tests
unary not looked through 1
any unary looked through 1
children branch forced to u32 0 — survives, and the comment says why

The survivor is recorded rather than papered over: an integer list carrying a
negative takes the extra_size path — probed with [1, -1], [-1] and
[_]i32{1, -1} — and the float case that does reach the children branch is
answered by any_float before the sign matters.

Full suite: 2645 passed, 0 failed. 19 seals refreshed in the same commit.

Refs #3459

670 `__auto_type x = { ... }` errors remained and had never been categorised.
Printing them BY SHAPE before writing any code split the wall into six
families:

    319  { 0 }                        an EMPTY list
    ~92  { cast_iN(N), ... }          calls
    ~85  { N, -N, ... }               a negative element
     32  { N.NeN }                    an exponent suffix
     21  { Trit.pos, ... }            enum member access
     12  { "s", "s" }                 strings

THE LARGEST FAMILY CANNOT BE INFERRED AT ALL, and finding that out is why the
measurement came first. `{ 0 }` comes from `var x = []`, of which the specs
contain 439. C11 has no `{}`, so `{ 0 }` is the emitter's stand-in, and an
empty list has nothing to take a type from. Naming one would be inventing it,
and a test now pins that it keeps `__auto_type`.

The tractable family was the negatives, 193 corpus sites. A negative element is
a UNARY EXPRESSION, not a literal, so the whole list was refused. Looking
through the `-` was the easy half; the first version then emitted

    uint32_t x[2] = { 1, -1 };

an unsigned type holding a negative -- exactly the quiet wrong answer this
class of repairs exists to avoid. A negative now makes the list `i32`.

MEASURED, whole corpus, -ferror-limit=0:

    errors                              14165 -> 14041
    __auto_type with initializer list     670 ->   523
    files better                           11

Two files worse, both unmasking. Sign diagnostics unchanged -- 7
`-Wsign-compare` and 60 conversions on both sides -- so the signed choice
introduced none. Across three passes the class has gone 1729 -> 523.

ONLY `-` IS LOOKED THROUGH. `[!1]` keeps `__auto_type`: a unary whose value is
not the literal underneath it would have the list typed from the wrong number.
A mutant widening this to any unary operator dies on that test.

A mutant forcing the children branch to "u32" SURVIVES, and it is written into
the comment rather than papered over: an integer list carrying a negative takes
the `extra_size` path -- probed with `[1, -1]`, `[-1]` and `[_]i32{1, -1}` --
and the float case that does reach the children branch is answered by
`any_float` before the sign matters. The branch is reachable; that combination
has not been produced.

19 seals refreshed in the same commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gHashTag
gHashTag enabled auto-merge (squash) September 8, 2026 04:59
@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 04:59:06 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)=3f3ef10c5ef1 != 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 d86df94 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.

1 participant