Skip to content

bugc: add push to dynamic arrays in storage - #366

Closed
gnidan wants to merge 1 commit into
bugc-fixed-array-layoutfrom
bugc-array-push
Closed

gnidan wants to merge 1 commit into
bugc-fixed-array-layoutfrom
bugc-array-push

Conversation

@gnidan

@gnidan gnidan commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Stacked on #364 (storage array layout), which this PR targets. Review that first.

BUG had no way to grow a dynamic array in storage. A write past the end was how such an array grew, but it left the length alone, so the array's pointer (which reads the length) showed nothing. This adds push, as Solidity has it, and checks indexes against the length.

Syntax. a.push(v) writes v at index a.length, then stores a.length + 1. a.push() adds a zero element: there is no pop or delete, so nothing can have written past the length. push() is what makes an array of arrays usable: m.push(); m[0].push(4);. BUG already parses a.push(v) as a call whose callee is the member access a.push, in the same place as .length, which is a member access. So no parser change was needed. The type checker used to reject any call whose callee was not an identifier. It now accepts push on a dynamic array in storage (directly, or inside a mapping or a struct), with at most one argument assignable to the element type. A push has no value, like a call to a function with no return type. push on a memory array or a fixed-size array is a type error.

Bounds. An index into a dynamic array in storage now reverts with Panic(0x32) unless it is less than the length in the array's slot, for reads and writes, as #344 does for memory. The push's own write at index length skips the check. An array literal's writes skip it too, because they store the length first.

.length in storage. a.length on a dynamic array in storage did not read the array's slot. It went through the memory length instruction on a value that is not a memory address, so the tests here read 0 at the top level and garbage for an inner array. It now reads the slot, through the same storage access chain as an element.

The nested-arrays.bug example wrote matrix[2][5] into empty arrays. It now pushes rows and elements first. In the BUG case study, the paragraph that said a write past the end grows the array now describes push.

Conflicts to expect: #355, #357 and #359 also change irgen/generate/expressions/access.ts, and #361 changes irgen/generate/storage.ts.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-07 03:10 UTC

@gnidan
gnidan force-pushed the bugc-fixed-array-layout branch from 9b8cfe6 to c0ab7fa Compare October 7, 2026 02:27
@gnidan

gnidan commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

Included in #368.

@gnidan gnidan closed this Oct 7, 2026
@gnidan
gnidan deleted the bugc-array-push branch October 7, 2026 03:07
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