gen-c: an enum member is a constant in both spellings - #3470
Merged
Conversation
Closes #3469 `Trit.pos` was fixed one pass earlier. `TokenKind::KwFn` is the SAME enum-member reference spelled with a path, and it was not: 917 `X::Y` occurrences reached the generated C across 65 files, and C has no `::` in an expression at all. MEASURED, whole corpus, -ferror-limit=0: errors 13331 -> 12420 (-911) files better/worse 27 / 0 compiling clean 303 -> 307 compiler_diagnostics 43 -> 0, compiler_lexer 133 -> 3, igla_race_formal 393 -> 257, file_operations 163 -> 85 ONE RULE, TWO SPELLINGS. Both arms now call one helper, so a change to the naming convention cannot reach one and miss the other. A mutant disabling either call site is killed by the other's tests. THE MEMBERSHIP TEST IS ON THE VARIANTS, NOT THE ENUM'S NAME. 12 corpus sites name a member their enum does not declare (`Trit::TRUE` against an enum of pos/neg/zero). Lowering those would emit a constant `gen_c_enum` never wrote -- a diagnostic that hides the spec's mistake instead of naming it. They stay loud, and the specs are what needs fixing. PREDICTED 526, DELIVERED 505, AND THE 21 ARE ACCOUNTED FOR EXACTLY: they sit inside emitted C comments (`/* invariant ... is not a C constant expression: (ErrorCode::Success == 0) */`), a path that prints source text verbatim rather than through the expression emitter, and they produce no errors. A gap between prediction and outcome is a question, not a rounding error. MY OWN READER OVER-COUNTED BY 9. `c_error_classes.py` searched for the word `error:`; clang echoes the offending source line under each message, so three lines of one spec containing `"error: "` in a STRING LITERAL were counted as diagnostics. It is anchored on `file:line:col: error: ` now, and the self-check gained the case that found it. The first version of that fixture put the string on a clean line -- clang never echoed it, the control could not fail, and it passed for the wrong reason. AND I MEASURED A MUTANT. After the mutation run I restored compiler.rs and did not rebuild, so the tool reported 13120 with `unexpected type name 'Trit'` back at 641 -- the numbers of the mutant that disables the dotted arm. Two of my own instruments disagreeing by 700 is what caught it. A GUARD WAS WRITTEN, FOUND UNREACHABLE, AND REMOVED: a variant name is an identifier, so the map can never hold `b::c` and a `!member.contains("::")` test could not change the outcome. `rsplit_once` survives as a mutant and is documented rather than papered over: for a two-segment path the two are identical, and for the 477 three-segment paths in the specs both refuse, because the map is keyed on a single identifier. Handling `lexer::TokenKind::RBrace` is a separate repair and is named in #3469, not assumed. CENSUS RE-BLESSED, AND THE DRIFT IS NOT THIS COMMIT'S. `workflow files read` 50 -> 51, `jobs` 71 -> 72, `run: steps` 235 -> 246. Stashing every change here and running `tri census pin --gate` on clean origin/master reproduces the failure, so it was already stale: ELEVEN workflow commits have landed since the pin was last blessed on 2026-09-05, every one of them by squash, and a squash does not run the hook. The pin binds local commits and nothing that reaches master. Tests: 5 new, full suite 3515 passed 0 failed. 34 stale seals refreshed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
September 8, 2026 08:38
Contributor
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
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.
gen-c: an enum member is a constant in both spellings
Closes #3469
Trit.poswas fixed one pass earlier.TokenKind::KwFnis the SAMEenum-member reference spelled with a path, and it was not: 917
X::Yoccurrences reached the generated C across 65 files, and C has no
::in an expression at all.
MEASURED, whole corpus, -ferror-limit=0:
errors 13331 -> 12420 (-911)
files better/worse 27 / 0
compiling clean 303 -> 307
compiler_diagnostics 43 -> 0, compiler_lexer 133 -> 3,
igla_race_formal 393 -> 257, file_operations 163 -> 85
ONE RULE, TWO SPELLINGS. Both arms now call one helper, so a change to
the naming convention cannot reach one and miss the other. A mutant
disabling either call site is killed by the other's tests.
THE MEMBERSHIP TEST IS ON THE VARIANTS, NOT THE ENUM'S NAME. 12 corpus
sites name a member their enum does not declare (
Trit::TRUEagainst anenum of pos/neg/zero). Lowering those would emit a constant
gen_c_enumnever wrote -- a diagnostic that hides the spec's mistake instead of
naming it. They stay loud, and the specs are what needs fixing.
PREDICTED 526, DELIVERED 505, AND THE 21 ARE ACCOUNTED FOR EXACTLY:
they sit inside emitted C comments (
/* invariant ... is not a C constant expression: (ErrorCode::Success == 0) */), a path that printssource text verbatim rather than through the expression emitter, and
they produce no errors. A gap between prediction and outcome is a
question, not a rounding error.
MY OWN READER OVER-COUNTED BY 9.
c_error_classes.pysearched for theword
error:; clang echoes the offending source line under eachmessage, so three lines of one spec containing
"error: "in a STRINGLITERAL were counted as diagnostics. It is anchored on
file:line:col: error:now, and the self-check gained the case thatfound it. The first version of that fixture put the string on a clean
line -- clang never echoed it, the control could not fail, and it
passed for the wrong reason.
AND I MEASURED A MUTANT. After the mutation run I restored compiler.rs
and did not rebuild, so the tool reported 13120 with
unexpected type name 'Trit'back at 641 -- the numbers of the mutant that disables thedotted arm. Two of my own instruments disagreeing by 700 is what caught
it.
A GUARD WAS WRITTEN, FOUND UNREACHABLE, AND REMOVED: a variant name is
an identifier, so the map can never hold
b::cand a!member.contains("::")test could not change the outcome.rsplit_oncesurvives as a mutant and is documented rather than paperedover: for a two-segment path the two are identical, and for the 477
three-segment paths in the specs both refuse, because the map is keyed
on a single identifier. Handling
lexer::TokenKind::RBraceis aseparate repair and is named in #3469, not assumed.
CENSUS RE-BLESSED, AND THE DRIFT IS NOT THIS COMMIT'S.
workflow files read50 -> 51,jobs71 -> 72,run: steps235 -> 246. Stashing everychange here and running
tri census pin --gateon clean origin/masterreproduces the failure, so it was already stale: ELEVEN workflow commits
have landed since the pin was last blessed on 2026-09-05, every one of
them by squash, and a squash does not run the hook. The pin binds local
commits and nothing that reaches master.
Tests: 5 new, full suite 3515 passed 0 failed. 34 stale seals refreshed.
🤖 Generated with Claude Code