Skip to content

fix(parser): const X = packed struct {} lost its name (cherry-pick of #3384) - #3385

Merged
gHashTag merged 1 commit into
fix/struct-field-brace-nestingfrom
fix/packed-struct-on-course-branch
Sep 6, 2026
Merged

fix(parser): const X = packed struct {} lost its name (cherry-pick of #3384)#3385
gHashTag merged 1 commit into
fix/struct-field-brace-nestingfrom
fix/packed-struct-on-course-branch

Conversation

@gHashTag

@gHashTag gHashTag commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Cherry-pick of #3384 onto the branch the website actually vendors.

Why it needed to come here separately

master and fix/struct-field-brace-nesting have diverged in both directions —
1327 commits on the branch that master lacks, 586 on master the branch
lacks. t27.ai vendors its corpus from this branch (1cd2877f9), so a fix
landed on master alone can never reach the site.

More usefully: master's corpus contains no packed struct at all, so master
could not test the fix. This branch is where specs/demos/hello_world.t27 lives —
the spec the Spec Explorer opens on — so this is the first place it was verified
end to end.

The conflict was real: the branch's union(enum) case occupies the slot the fix
used on master. Resolved by keeping both, side by side ahead of KwStruct.

Measured, same branch, same spec, only the parser differing

// before
parameter [31:0] Greeting = packed;
// struct
reg [7:0] _length;              // .length
reg signed [7:0] _trit;         // .trit

// after
// struct Greeting
reg [7:0] greeting_length;      // Greeting.length
reg signed [7:0] greeting_trit; // Greeting.trit

The struct was already being emitted — anonymously, because the declaration
was a ConstDecl. The fix removes the bogus parameter and restores the name.

What it does not do — measured, not assumed

yosys 0.63 synthesises both versions to 0 cells, 4 wires, 4 ports. It never
rejected the old output either; it printed:

Lexer warning: The SystemVerilog keyword `packed' is not recognized
unless read_verilog is called with -sv!

and carried on.

So this removes a warning and restores a lost name. It does not change
synthesis, and it was never a cause of the corpus's yosys failures.
I speculated
otherwise two iterations ago; the refutation belongs next to the fix rather than
left standing in an older commit message. The module-shell / 0-LUT condition has a
different root cause — no hardware boundary — which the entry-points service
already measures at 387 specs.

Verification

  • Suite green on this branch: 889 plus the per-crate suites, 0 failed
  • FROZEN_HASH resealed with a shasum-computed digest, never transcribed
  • Cargo.lock left alone: cargo build -p t27c prunes ~1000 lines from it, which
    is a build artifact and not a change

Closes #3383

#3384)

There is no KwPacked in this lexer -- `packed` arrives as an Ident, exactly like
`union` does. parse_const_decl handled `= struct {` and `= union(enum) {` but not
`= packed struct {`, so the declaration fell through to the generic expression
path and became a ConstDecl whose initializer started at that token.

Cherry-picked from master (f5d8564). Master's corpus contains no `packed
struct` at all, so master could not test the fix. THIS branch is where
specs/demos/hello_world.t27 lives -- the spec the Spec Explorer opens on -- so
it is the first place the fix could be verified end to end. The conflict was
real and resolved by keeping both: the branch's `union(enum)` case occupies the
slot the fix used on master, and both now sit side by side ahead of KwStruct.

Measured on hello_world, same branch, same spec, only the parser differing.

    before:  parameter [31:0] Greeting = packed;
             // struct
             reg [7:0] _length;         // .length
             reg signed [7:0] _trit;    // .trit

    after:   // struct Greeting
             reg [7:0] greeting_length;        // Greeting.length
             reg signed [7:0] greeting_trit;   // Greeting.trit

So the struct was already being emitted -- anonymously, because the declaration
was a ConstDecl. The fix removes the bogus parameter and restores the name.

WHAT IT DOES NOT DO, measured rather than assumed. yosys 0.63 synthesises both
versions to 0 cells, 4 wires, 4 ports. It never rejected the old output either:
it printed

    Lexer warning: The SystemVerilog keyword `packed' is not recognized
    unless read_verilog is called with -sv!

and carried on. So this removes a warning and restores a lost name; it does not
change synthesis, and it was never a cause of the corpus's yosys failures. I had
speculated otherwise two iterations ago and am recording the refutation next to
the fix rather than leaving the guess in a commit message. The module-shell /
0-LUT condition has a different root cause -- no hardware boundary -- which the
`entry-points` service already measures at 387 specs.

Suite green on this branch: 889 plus the per-crate suites, 0 failed. FROZEN_HASH
resealed with a shasum-computed digest, never transcribed. Cargo.lock was left
alone: `cargo build -p t27c` prunes ~1000 lines from it, which is a build
artifact and not a change.

Closes #3383
@gHashTag
gHashTag merged commit b691a1b into fix/struct-field-brace-nesting Sep 6, 2026
12 of 13 checks passed
@gHashTag
gHashTag deleted the fix/packed-struct-on-course-branch branch September 6, 2026 14:23
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