Skip to content

fix(rust): the Zig-shaped array [N]T discards its length (+4, -1 stated) - #3247

Merged
gHashTag merged 7 commits into
masterfrom
zig-array-loses-its-length
Sep 5, 2026
Merged

gHashTag merged 7 commits into
masterfrom
zig-array-loses-its-length

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 5, 2026

Copy link
Copy Markdown
Owner

The mapper has both array branches and the Zig-shaped one throws the size away:

[4]u8   ->  Vec<u8>      the length 4 is gone, and Vec cannot stand in a const
[u8; 4] ->  [u8; 4]      correct

The answer was already forty lines above in the same function, and its comment records
the history: "Previously only the Zig-style [N]T form was handled". The two swapped
places and one was left behind.

Measured against a pinned binary

accepts, before 315
after 318
gained +4
regressed −1

The trade is stated in the open rather than buried. One spec regresses and it is
specs/tri/trees/octree.t27, whose field is children : [8]?OctNode — a fixed array
of the struct it lives in. As Vec<Option<OctNode>> it compiled, because a Vec
supplies indirection by accident while discarding the length; as
[Option<OctNode>; 8] it is honestly infinitely sized and rustc says so.

Neither lowering is right. The correct Rust is [Option<Box<OctNode>>; 8], which keeps
both the length and the indirection, and that is recorded here for whoever takes it —
it needs the enclosing type's name inside t27_type_to_rust, which is a static
function with 18 call sites, so it is not a mapper tweak.

The siblings do not settle it either: the C output for that spec is already invalid
(?OctNode* children; — the optional leaked), and Zig's acceptance is the shallow
build-obj reading that does not analyse unreferenced declarations.

A regression this change caused, and the measurement caught

The first version read everything inside the brackets as a size and produced
[T; * as usize] from [*]T — the source language's many-item pointer, where the
* is not a length. That cost a second regression until the guard was added: anything
inside the brackets that is not a digit string or a plain identifier keeps the previous
unsized lowering.

Both regressions came from the same omission — I enumerated the branches of the
bracket syntax and not the contents of the brackets.

On provenance

This cause was surfaced by a fan-out audit whose measurements I then invalidated by
rebuilding the compiler underneath it — one agent reported "THE RULER MOVED UNDER
ME"
, and it was right. The workflow was stopped and its counts discarded. This finding
was re-derived by hand against a binary pinned at /tmp/t27c-pinned, and every number
above comes from that pinned copy.

Closes #3246

gHashTag and others added 3 commits September 5, 2026 10:12
compiler.rs:8322 maps "str" | "string" to []const u8 for Zig and
compiler.rs:18248 maps it to const char* for C. compiler.rs:24426 mapped it to
the owned String for Rust, and String is not constructible in a `const` item,
which is where the corpus mostly uses it:

    pub const DEFAULT_NOTEBOOK: String = "t27-QUEEN-BRAIN";
    error[E0308]: expected `String`, found `&str`

48 of the 75 specs whose first error was E0308 carried that mismatch.

Measured by name over all 650 corpus specs: rustc accepts 288 -> 314, +26, zero
regressions.

The judgement is stated rather than hidden. `&'static str` is narrower than
String -- a field of that type holds only a string living for the program -- and
that narrowing is what both siblings already chose, neither []const u8 nor
const char* owning its bytes. Zero regressions says nothing in the corpus needed
the owned form.

Also records the boundary my predictor from #3219 was missing. That rule ties a
fix's yield to the stub-bodied share of its class; this class is 3% stub-bodied
and I predicted +2..+8 against a measured +26. The rule holds for a fix repairing
a SIGNATURE while leaving a body, and not for one repairing a COMPLETE
DECLARATION: a const is correct or not on its own.

Seal and 92 drifted seals move in the same commit.

Closes #3239

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ositions (+1)

A spec field may be named `type`, `ref` or `match`. Those are Rust keywords and
the emitter wrote them bare, so the struct did not parse. `r#type` is the exact
spelling and needs no judgement.

The name is written in four places -- the field declaration, a field access, a
function parameter and a struct literal -- and repairing the first two changed
nothing beyond one spec. Repairing all four changed nothing further: the remaining
specs of the class carry other defects behind the keyword.

Measured by name over 650 specs: 314 -> 315, +1, zero regressions. The honest
measure here is closure, not yield: `found keyword `type`` as a first error goes
7 -> 1, and the residue is a different cause (keywords in TYPE position, from
#3225's list-valued declaration).

crate/self/Self/super are deliberately not escaped: `r#` is invalid for them, so
escaping would swap one parse error for another.

Also records a measurement flaw that has misled me three times: taking the LAST
numbered line of rustc's first error block reads back the SUGGESTION, since
suggestions render as numbered lines and come last. It produced a phantom
`pub struct ListNode<T>` earlier and made two specs here look already-repaired.

Closes #3241

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The mapper has both array branches and the Zig-shaped one throws the size away:
`[4]u8` becomes Vec<u8> while `[u8; 4]` becomes `[u8; 4]`. The right answer was
already forty lines above in the same function, whose comment records that only
the Zig spelling used to be handled. The two swapped places and one was left
behind.

Measured against a binary pinned at /tmp/t27c-pinned: 315 -> 318, +4, -1.

THE TRADE IS STATED RATHER THAN BURIED. The regression is octree.t27, whose field
is `children : [8]?OctNode` -- a fixed array of the struct it lives in. As
Vec<Option<OctNode>> it compiled because a Vec supplies indirection by accident
while discarding the length; as [Option<OctNode>; 8] it is honestly infinitely
sized. Neither is right: the correct Rust is [Option<Box<OctNode>>; 8], which
needs the enclosing type name inside a static function with 18 call sites.

A second regression was caught before shipping: reading everything in the brackets
as a size produced `[T; * as usize]` from `[*]T`, the many-item pointer. Guarded --
contents that are not a digit string or a plain identifier keep the unsized
lowering. Both regressions came from one omission: I enumerated the branches of the
bracket syntax and not the contents of the brackets.

Provenance: this cause was surfaced by a fan-out audit whose measurements I then
invalidated by rebuilding the compiler underneath it. One agent reported "THE RULER
MOVED UNDER ME" and was right; the workflow was stopped and its counts discarded.
Everything above is re-derived by hand against the pinned copy.

Closes #3246

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

github-actions Bot commented Sep 5, 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 5, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-05 04:28:26 UTC

Summary

Status Count
Total Open PRs 20
PRs with Failing Checks 17
PRs with All Checks Green 3
READY 0
FAILING 17
PENDING 0

Seal Status

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

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-05 04:28:54 UTC

Summary

Status Count
Total Open PRs 20
PRs with Failing Checks 17
PRs with All Checks Green 3
READY 0
FAILING 17
PENDING 0

Seal Status

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

…-length

# Conflicts:
#	.trinity/seals/ApbBridge.json
#	.trinity/seals/BoardMinimalXC7A100T.json
#	.trinity/seals/EmitterXDC.json
#	.trinity/seals/File.json
#	.trinity/seals/Git.json
#	.trinity/seals/GitDiff.json
#	.trinity/seals/GitOperations.json
#	.trinity/seals/Hir.json
#	.trinity/seals/Lexing.json
#	.trinity/seals/Linking.json
#	.trinity/seals/MAC_Testbench.json
#	.trinity/seals/NotebookLM.json
#	.trinity/seals/PhiRatio.json
#	.trinity/seals/PhiSplitOptimality.json
#	.trinity/seals/PhiUniversalAttractor.json
#	.trinity/seals/PinsIR.json
#	.trinity/seals/Project.json
#	.trinity/seals/SacredVerification.json
#	.trinity/seals/Session.json
#	.trinity/seals/Stdlib.json
#	.trinity/seals/TernaryIsa.json
#	.trinity/seals/Top_Level_Testbench.json
#	.trinity/seals/VcdConformanceCompare.json
#	.trinity/seals/Zamolodchikov4DConjecture.json
#	.trinity/seals/base-ring-32.json
#	.trinity/seals/base_base-ring-32.json
#	.trinity/seals/boards_BoardMinimalXC7A100T.json
#	.trinity/seals/cloud-railway-deploy.json
#	.trinity/seals/cloud_cloud-railway-deploy.json
#	.trinity/seals/compiler_Lexing.json
#	.trinity/seals/compiler_Linking.json
#	.trinity/seals/compiler_Stdlib.json
#	.trinity/seals/file_File.json
#	.trinity/seals/fpga_ApbBridge.json
#	.trinity/seals/fpga_FpgaStdlib.json
#	.trinity/seals/fpga_Hir.json
#	.trinity/seals/fpga_Memory.json
#	.trinity/seals/fpga_Stdlib.json
#	.trinity/seals/fpga_TernaryIsa.json
#	.trinity/seals/fpga_VcdConformanceCompare.json
#	.trinity/seals/git_Git.json
#	.trinity/seals/git_GitDiff.json
#	.trinity/seals/git_GitOperations.json
#	.trinity/seals/github::comments.json
#	.trinity/seals/github::issues.json
#	.trinity/seals/github::prs.json
#	.trinity/seals/github_github::comments.json
#	.trinity/seals/github_github::issues.json
#	.trinity/seals/github_github::prs.json
#	.trinity/seals/math_PhiSplitOptimality.json
#	.trinity/seals/math_PhiUniversalAttractor.json
#	.trinity/seals/memory_NotebookLM.json
#	.trinity/seals/nn_GatedLinearAttention.json
#	.trinity/seals/numeric_PhiRatio.json
#	.trinity/seals/physics_SacredVerification.json
#	.trinity/seals/physics_Zamolodchikov4DConjecture.json
#	.trinity/seals/pins_EmitterXDC.json
#	.trinity/seals/pins_PinsIR.json
#	.trinity/seals/race_igla-race-formal.json
#	.trinity/seals/server_Project.json
#	.trinity/seals/server_Session.json
#	.trinity/seals/testbench_MAC_Testbench.json
#	.trinity/seals/testbench_Top_Level_Testbench.json
#	bootstrap/stage0/FROZEN_HASH
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-05 06:32:00 UTC

Summary

Status Count
Total Open PRs 17
PRs with Failing Checks 11
PRs with All Checks Green 6
READY 0
FAILING 11
PENDING 0

Seal Status

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

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

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

…-length

# Conflicts:
#	.trinity/seals/Hir.json
#	.trinity/seals/bus-schema.json
#	.trinity/seals/bus_bus-schema.json
#	.trinity/seals/config-paths.json
#	.trinity/seals/config_config-paths.json
#	.trinity/seals/fpga_Hir.json
#	.trinity/seals/parser_trilexer.json
#	.trinity/seals/provider-transform.json
#	.trinity/seals/provider_provider-transform.json
#	.trinity/seals/server-mdns.json
#	.trinity/seals/server_server-mdns.json
#	.trinity/seals/trilexer.json
#	bootstrap/src/compiler.rs
#	bootstrap/stage0/FROZEN_HASH
@github-actions

github-actions Bot commented Sep 5, 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 5, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-05 07:17:18 UTC

Summary

Status Count
Total Open PRs 14
PRs with Failing Checks 13
PRs with All Checks Green 1
READY 0
FAILING 13
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=de6cd4b1b116 != 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 5, 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 42cb425 into master Sep 5, 2026
30 of 31 checks passed
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-09-05 07:29:12 UTC

Summary

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

Seal Status

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

The Zig-shaped array [N]T discards its length; the right branch is forty lines above

1 participant