Repository navigation
fix(compiler): lower slice-to-array conversions with Go's length check - #23
Merged
Mister-Meeseeks merged 1 commit intoOct 19, 2026
Merged
Conversation
(*[N]T)(s) passed Check and then failed the built-in backend's C compile (CrocSwap#7): the pointer-conversion rule never looked at the operand, so the emitter cast the C slice struct to a pointer. [N]T(s) was rejected. Both now follow Go. len(s) < N aborts with the bounds trap; the pointer is the slice's data pointer, so writes through either view see each other, and a nil slice gives nil (only N == 0 reaches it); the array is a copy of the first N elements, and [0]T(s) reads nothing. Both are plain operations in gc's evaluation order: calls in the same statement run first, so their panics win and a slice they replace is the one converted. Initializers that convert run at run time instead of at compile time, where the interpreter returned the slice as the pointer. gosvm features reports slice_array_conversions. Host differentials against native Go (output bytes, writes before a failure, panic lines) and SBF runs on fogo-v0 and solana-v3. The corpus's one recorded slice conversion now compiles; every example ELF and the reference ELFs are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
(*[8]byte)(b)passesgosvm checkand native tests, thengosvm buildfails on both targets: the(*T)(p)rule never looked at the operand, so the backend cast the Cslicestruct to a pointer.[N]T(s)was rejected by Check outright.Solution
Both forms now follow Go:
len(s) < Naborts with the existing bounds trap, no new code(*[N]T)(s)is the slice's data pointer, so writes through either view (account data included) see each other; a nil slice gives nil, which onlyN == 0reaches[N]T(s)copies the firstNelements;[0]T(s)reads nothingBoth are plain operations in gc's order: in
(*[8]byte)(b)[0] + f(),fruns first, its panic wins, and abit replaced is the one converted. Converting package initializers run at run time; the compile-time evaluator used to return the slice as the pointer and panic.gosvm featuresreportsslice_array_conversions. ERROR_CONTRACT changelog entry included (announce to Qushta).Tests
TestSliceArray*: two programs, 256 inputs each, native Go (host 1.23.2) vs host C, comparing output, writes before a failure and panic lines:len == N,len > N,len < N, aliasing, nil and empty slices, struct/array/generic elements, nested generics, escapes, initializers, evaluation order.examples/*gosvm projects, a fresh starter and the 4 reference ELFs build byte-identical to79cf25c. The frozen corpus's one slice conversion ([24]byte(s)) now compiles, recorded incorpusChanges.make testpasses apart from the knownTestStdlib*andTestFullSwapFactshost failures.Linked work
Closes #7. hyperlane-xyz/hyperlane-monorepo#9852 worked around it by copying keys into a
[32]byte. Evidence:results/compiler/2026-10-19-slice-array-conversions. Conflicts with the #8 fix on ERROR_CONTRACT and HANDOFF are mechanical.