Skip to content

feat(typecheck): a constant must fit the type it declares - #2926

Merged
gHashTag merged 3 commits into
masterfrom
w760
Aug 30, 2026
Merged

feat(typecheck): a constant must fit the type it declares#2926
gHashTag merged 3 commits into
masterfrom
w760

Conversation

@gHashTag

Copy link
Copy Markdown
Owner
const EXP_OFFSET: u32 = 1792...173      // 185 digits
Typecheck OK (0 errors, 0 warnings)
backend emitted
Rust pub const EXP_OFFSET: u32 = 1792…173;
Verilog localparam [31:0] OFFSET_MAX = 3584…346;
C #define EXP_OFFSET 1792…173
cc error: integer literal is too large to be represented in any integer type

Three of four backends carried a ~590-bit value in a 32-bit box without a word.
The fourth is the only reason anyone noticed. Ten constants, five specs, the
whole gft ladder (#2925).

Signed types hold one bit fewer, so const X: i32 = 3000000000 is caught too —
the same defect at a size cc never complains about, because it fits uint64_t.

The reading that was wrong first

The C backlog is 404 specs that generate C cc refuses. Ranked by first
error, the top family was the scaffold helpers: default_input 47,
valid_input 27. That looked like the lever.

Measured before building anything:

rejected files                                   404
  ... carrying a scaffold error                  166
  ... where that is the ONLY family                0

Zero. Every one of the 166 has other independent errors. Ranking by first
error ranks by position in the file, not by blocking power.

distinct error families per file:
  1 family:  20 files      <- the only real levers
  2:  42    3:  31    4:  78    5:  52    6:  45    7:  40    8+:  96

This defect came from four of those twenty.

Two dead branches in my own first draft

Each had a comment explaining why it was necessary. Each mutation changed no
test, so both are gone:

branch comment claimed actually
if d.len() > 20 { return false } parsing 185 digits into u128 would overflow parse::<u128> returns Err; the Err arm already answers
.filter(|c| *c != '_') separators are not digits the lexer strips them before this check sees the literal

The comments now say what is load-bearing. Err(_) => false is the arm that
does the work, and flipping it to true fails
a_literal_too_wide_for_u128_is_still_rejected.

Mutation-checked

mutation test that fails
i32 given 32 value bits a_signed_type_holds_one_bit_fewer
Err(_) => true a_literal_too_wide_for_u128_is_still_rejected

Tests drive the shipped binary, not a library call — this crate has no lib
target, and a test that reimplemented the check would pass against a compiler
that never shipped it.

Ledger

The five specs are recorded, not edited: which number is meant is a question
about the GF-T ladder's definition (the header says E_t = 391), not about the
compiler. 150 → 155, reason written into the file. Newly detected, not newly
broken.

Closes #2925

    const EXP_OFFSET: u32 = 1792...173      // 185 digits
    Typecheck OK (0 errors, 0 warnings)

Rust emitted `pub const EXP_OFFSET: u32 = 1792...173;`, Verilog emitted
`localparam [31:0] OFFSET_MAX = 3584...346;`, C emitted the `#define`. Only cc
said anything -- "integer literal is too large to be represented in any integer
type" -- and it is the fourth backend, so three of four carried a ~590-bit value
in a 32-bit box without a word.

Ten constants across five specs, the whole `gft` ladder. The digit count roughly
doubles per rung, so they look computed; the file header says the quantity is
`E_t = round((N-1)/phi^2) = 391`.

Signed types hold one bit fewer, so `const X: i32 = 3000000000` is caught too --
the same defect at a size cc never complains about, because it fits uint64_t.

HOW THIS WAS FOUND, and the reading that was wrong first. The C backlog ranked by
FIRST error put the scaffold helpers on top: `default_input` 47, `valid_input`
27. Measured before building anything: of the 166 files carrying that error,
ZERO would compile if it were the only fix. Ranking by first error ranks by
position in the file, not by blocking power. Only 20 of 404 files are blocked by
exactly one family; the median carries four or five. This defect came from four
of those twenty.

TWO BRANCHES OF THE FIRST DRAFT WERE DEAD, each with a comment explaining why it
was necessary. A `len() > 20` guard "because parsing 185 digits into u128 would
overflow" -- `parse::<u128>` returns `Err`, and the `Err` arm already answers.
A filter stripping `_` "because separators are not digits" -- the lexer strips
them before the check sees the literal. Both mutations changed no test, so both
are gone and the comments now say what is actually load-bearing.

The five specs go in the expectations ledger rather than being edited: which
number is meant is a question about the GF-T ladder's definition, not about the
compiler. 150 -> 155 with the reason in the file. Nothing regressed -- this is
newly detected, not newly broken.

Closes #2925
# Conflicts:
#	bootstrap/stage0/FROZEN_HASH
#	docs/reports/suite_expectations.json
@github-actions

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

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

@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-30 00:37:35 UTC

Summary

Status Count
Total Open PRs 8
PRs with Failing Checks 7
PRs with All Checks Green 1
READY 0
FAILING 7
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=7d3956bee444 != 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).

@github-actions

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

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

@gHashTag
gHashTag merged commit 6553b86 into master Aug 30, 2026
28 of 29 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-30 00:38:36 UTC

Summary

Status Count
Total Open PRs 7
PRs with Failing Checks 7
PRs with All Checks Green 0
READY 0
FAILING 7
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=7d3956bee444 != 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).

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.

Ten constants declare a type they cannot fit; three of four backends emit them verbatim

1 participant