Skip to content

Enhance array comparison with better type checks, and change inferred array size behaviour#86

Merged
someone235 merged 9 commits intokaspanet:masterfrom
someone235:fix-byte-bytes-bug
Mar 27, 2026
Merged

Enhance array comparison with better type checks, and change inferred array size behaviour#86
someone235 merged 9 commits intokaspanet:masterfrom
someone235:fix-byte-bytes-bug

Conversation

@someone235
Copy link
Copy Markdown
Contributor

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] == byte
  • int == bool
  • int[] == 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 allowed
  • byte[M] -> byte[N] is rejected when M != N

In 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:

  byte x = 5;
  byte y = 7;
  require(x + y > 0);
  byte x = 5;
  byte y = 7;
  byte z = x + y;

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;

  byte x = 5;
  require(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 casts

A 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:

  • Cast slices explicitly when comparing to fixed-size hashes:

require(hash == byte[32](route_templates.slice(256, 288)));

  • Cast fixed arrays to dynamic arrays when comparing against byte[]:

require(x == byte[](y));

  • Convert bytes to integers explicitly before numeric use:

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:

  • raw bytes
  • fixed-size byte sequences
  • dynamic arrays
  • numeric values

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.

@someone235 someone235 merged commit f57c898 into kaspanet:master Mar 27, 2026
4 checks passed
@someone235 someone235 deleted the fix-byte-bytes-bug branch March 27, 2026 08:56
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