Skip to content

tools: a parity table for builtin call spellings - #3500

Merged
gHashTag merged 1 commit into
masterfrom
c/builtin-parity-table
Sep 8, 2026
Merged

tools: a parity table for builtin call spellings#3500
gHashTag merged 1 commit into
masterfrom
c/builtin-parity-table

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 8, 2026

Copy link
Copy Markdown
Owner

tools: a parity table for builtin call spellings

Closes #3499

Five defects this campaign shared one shape -- a rule present in three
backends and missing from the fourth:

Type.member / Type::member gen-c had no answer #3467 #3469
. versus -> gen-c had no answer #3477
a brace literal as a value gen-c had no answer #3475 #3492
s.len on a string gen-c had no answer #3489
cast_iN(x) gen-c had no answer #3497

The cause is structural: FOUR INDEPENDENT AST-TO-TEXT EMITTERS, so a
lowering written in one cannot reach the others and the class recurs by
construction. Each was found by accident and cost a full pass.

backend_parity_table.py already asks this about DECLARATION FORMS.
This asks it about CALLS -- the other axis -- and printed the sixth
instance on its first run:

call uses specs C Rust Zig
abs(v) 392 45 passthrough (v).abs() @abs(v)
round(v) 136 38 passthrough (v).round() @round(v)
sqrt(v) 100 25 passthrough (v).sqrt() @sqrt(v)
floor(v) 98 15 passthrough (v).floor() @floor(v)
max(v, v) 51 26 passthrough (v).max(v) @max(v, v)
min(v, v) 19 12 passthrough (v).min(v) @min(v, v)
sign(v) 63 48 passthrough passthrough passthrough

796 uses across 45+ specs. sign is the other kind of row: nobody
lowers it, which is a question for the language rather than a backend.

FOR THREE OF THE SIX THE SPELLING WAS NEVER WRONG. sqrt(x) IS C, and
the only thing missing was <math.h>; the whole repair is a conditional
include, decided the way <string.h> and <assert.h> already are.

errors 10 831 -> 10 811 (-20)
files better/worse 10 / 0
headers with math.h 0 -> 10

abs IS DELIBERATELY EXCLUDED, and the reason is the shape this
campaign has refused four times: C has abs for int and fabs for
double, and choosing without the argument's type is a silent
truncation. min and max are not C functions at all.

IT CANNOT BE A GATE. A blank column is not a defect by itself: print
has no business in synthesizable Verilog and the float cast is refused
deliberately in three backends. The table proposes; a person concludes.

AND THE READER WAS WRONG ONCE, in exactly the way its sibling's
docstring records: the first version read Zig's @abs(v) as passthrough
-- abs( occurs inside it -- and called six lowered rows missing, a
failure of the instrument printed as a fact about the backend. The @
is in the lookbehind now, and the self-check asserts that case.

Tests: 5 new, full suite 3563 passed 0 failed. Five mutants, all killed,
including the two that widen or narrow the recognised set. 10 stale
seals refreshed.

🤖 Generated with Claude Code

Closes #3499

Five defects this campaign shared one shape -- a rule present in three
backends and missing from the fourth:

  Type.member / Type::member   gen-c had no answer   #3467 #3469
  `.` versus `->`              gen-c had no answer   #3477
  a brace literal as a value   gen-c had no answer   #3475 #3492
  `s.len` on a string          gen-c had no answer   #3489
  cast_iN(x)                   gen-c had no answer   #3497

The cause is structural: FOUR INDEPENDENT AST-TO-TEXT EMITTERS, so a
lowering written in one cannot reach the others and the class recurs by
construction. Each was found by accident and cost a full pass.

`backend_parity_table.py` already asks this about DECLARATION FORMS.
This asks it about CALLS -- the other axis -- and printed the sixth
instance on its first run:

  call        uses  specs   C            Rust           Zig
  abs(v)       392     45   passthrough  (v).abs()      @abs(v)
  round(v)     136     38   passthrough  (v).round()    @round(v)
  sqrt(v)      100     25   passthrough  (v).sqrt()     @sqrt(v)
  floor(v)      98     15   passthrough  (v).floor()    @floor(v)
  max(v, v)     51     26   passthrough  (v).max(v)     @max(v, v)
  min(v, v)     19     12   passthrough  (v).min(v)     @min(v, v)
  sign(v)       63     48   passthrough  passthrough    passthrough

796 uses across 45+ specs. `sign` is the other kind of row: nobody
lowers it, which is a question for the language rather than a backend.

FOR THREE OF THE SIX THE SPELLING WAS NEVER WRONG. `sqrt(x)` IS C, and
the only thing missing was `<math.h>`; the whole repair is a conditional
include, decided the way `<string.h>` and `<assert.h>` already are.

  errors            10 831 -> 10 811   (-20)
  files better/worse    10 / 0
  headers with math.h    0 -> 10

`abs` IS DELIBERATELY EXCLUDED, and the reason is the shape this
campaign has refused four times: C has `abs` for int and `fabs` for
double, and choosing without the argument's type is a silent
truncation. `min` and `max` are not C functions at all.

IT CANNOT BE A GATE. A blank column is not a defect by itself: `print`
has no business in synthesizable Verilog and the float cast is refused
deliberately in three backends. The table proposes; a person concludes.

AND THE READER WAS WRONG ONCE, in exactly the way its sibling's
docstring records: the first version read Zig's `@abs(v)` as passthrough
-- `abs(` occurs inside it -- and called six lowered rows missing, a
failure of the instrument printed as a fact about the backend. The `@`
is in the lookbehind now, and the self-check asserts that case.

Tests: 5 new, full suite 3563 passed 0 failed. Five mutants, all killed,
including the two that widen or narrow the recognised set. 10 stale
seals refreshed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gHashTag
gHashTag enabled auto-merge (squash) September 8, 2026 13:47
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-08 13:47:28 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)=602e6e213a60 != 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

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.

@gHashTag
gHashTag merged commit cf51434 into master Sep 8, 2026
30 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.

tools: a parity table for builtin CALL spellings -- the sixth instance printed on its first run

1 participant