Enhance array comparison with better type checks, and change inferred array size behaviour#86
Merged
someone235 merged 9 commits intokaspanet:masterfrom Mar 27, 2026
Merged
Conversation
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.
This PR tightens SilverScript’s type system around bytes, fixed-size byte arrays, array comparisons, and inferred array sizes.
The main language-level shift is that SilverScript now distinguishes more clearly between numeric values and raw byte data. Code that previously relied on implicit coercions or loose
comparisons will now need explicit casts or explicit numeric conversion.
Breaking Changes
Comparisons now require compatible types
Comparisons are stricter across scalar and array types.
Examples that now fail unless explicitly cast:
byte[] == byte[32]byte[32] == byteint == boolint[] == int[1]This is a breaking change for contracts that relied on implicit comparison coercions.
Fixed-size byte-array casts are stricter
Fixed-size byte-array casts now follow these rules:
byte[] -> byte[N]is allowedbyte[M] -> byte[N]is rejected whenM != NIn other words,
byte[32](x)is now interpreted as “treat this byte sequence as 32 bytes”, not as a reshaping/truncation/padding mechanism between different fixed sizes.This is a breaking change for code that previously used casts like:
byte[31](hash32)byte[32](hash31)byte no longer behaves like a small int for arithmetic
byte is now treated as raw one-byte data rather than a numeric scalar for arithmetic.
Examples that now fail:
If numeric behavior is intended, code must convert explicitly to an integer representation first.
This is a breaking change for any contract using byte in arithmetic expressions.
byte integer literals are now range-checked
Assignments and comparisons involving byte only accept integer literals in 0..=255.
Examples that now fail:
byte x = 256;This is a breaking change for contracts that treated byte as an unconstrained numeric alias.
Inferred array sizes are stricter
type[_]now means the compiler must infer a concrete fixed size from the initializer.If no concrete size can be inferred, compilation fails.
This is a breaking change for code that used inferred-size syntax as if it were equivalent to a dynamic array.
Behavior Changes
byte literals are compiled as raw bytes
A declaration like:
byte x = 5;now means “raw byte 0x05”, not “minimally encoded numeric 5”.
This makes scalar byte consistent with raw byte data elsewhere in the language.
Byte comparisons use byte semantics
When the left-hand side is a scalar byte, an integer literal on the right-hand side is treated as a byte literal if it is in range.
Example:
require(king_side_right == 1);This is now byte equality, not numeric equality.
byte[] -> byte[N]casts are reinterpret-style castsA cast such as:
byte[32](route_templates.slice(hash_start, hash_end))now means “trust this result is 32 bytes”, rather than converting a numeric value into a fixed-width byte encoding.
That makes fixed-size byte-array casts behave more like type assertions over existing byte data.
Source-Level Migration Guidance
Contracts may now need explicit casts or conversions in places that previously compiled implicitly.
Common migration patterns:
require(hash == byte[32](route_templates.slice(256, 288)));require(x == byte[](y));int piece = OpBin2Num(piece_byte);Impact
This PR is intentionally stricter and includes multiple breaking language changes.
The goal is to make SilverScript more predictable by enforcing a clearer separation between:
That improves correctness for contracts that manipulate hashes, templates, encoded state, and other fixed-layout binary data, but existing code that relied on implicit coercions will
need to be updated.