Skip to content

Implement __mem_repr_eq intrinsic - #7697

Merged
ironcev merged 6 commits into
masterfrom
ironcev/mem-repr-id-intrinsics
Jul 27, 2026
Merged

ironcev merged 6 commits into
masterfrom
ironcev/mem-repr-id-intrinsics

Conversation

@ironcev

@ironcev ironcev commented Jul 24, 2026 •

Copy link
Copy Markdown
Member

Description

This PR introduces a new __mem_repr_eq intrinsic for comparing memory representation of types, and removes the existing __runtime_mem_id and __encoding_mem_id intrinsics.

We decided to introduce __mem_repr_eq to mitigate the following issues we had with existing intrinsics:

  • mem_ids were u64 values computed using DefaultHasher whose results are not guaranteed to be stable across different runs of the same Sway compiler or being same on different target architectures.
  • even if we switched to a stable hasher, hashing to u64 was not giving a strong no-collision guarantee. A hash collision between different, e.g. runtime and encoding representation, would in case of false positives result in wrong encoding or decoding.

The __mem_repr_eq is defined as:

__mem_repr_eq<T>(repr_a: str, repr_b: str) -> bool

It returns true if the memory representation repr_a of the type T is equal to its memory representation repr_b, assuming T has both memory representations. If T does not have any of the representations repr_a or repr_b, returns false.

The valid values for repr_a and repr_b are "runtime", "encoding", and "hashing":

  • "runtime" is how the type is represented inside the VM's memory. This is the Sway runtime memory representation (e.g., struct fields are aligned to word boundaries, arrays are packed, etc.). This memory representation is defined for every type.
  • "encoding" is the packed memory representation of a type, as defined by the canonical ABI encoding. Not all types have a canonical ABI encoding defined, e.g., dynamic types like Vec or raw_slice. In that case, "encoding" never compares equal to any other memory representation, including to itself.
  • "hashing" is the packed memory representation of a type, as defined by the canonical hashing introduced in Optimize hashing by implementing is_hash_trivial #7695. Not all types have a canonical hashing defined, e.g., dynamic types like Vec or raw_slice. In that case, "hashing" never compares equal to any other memory representation, including to itself.

To test if a type T has "encoding" or "hashing" memory representation defined, compare that representation to itself. E.g.: let has_encoding_repr = __mem_repr_eq<T>("encoding", "encoding");

repr_a and repr_b must be compile-time constant strs, whose values are one of "runtime", "encoding", or "hashing". The constant strs never end up in the bytecode.

Additionally, the PR moves existing E2E intrinsics tests that were not in the language/intrinsics into language/intrinsics.

Breaking Change

The old __runtime_mem_id and __encoding_mem_id intrinsics are removed. The code that is using them must switch to the new __mem_repr_eq.

Checklist

  • I have linked to any relevant issues.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • I have requested a review from the relevant team or maintainers.

@ironcev ironcev self-assigned this Jul 24, 2026
@cursor

cursor Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

PR Summary

High Risk
This is a breaking compiler intrinsic change that alters how ABI encode/decode and hash triviality are decided across the standard library, so any mismatch in representation logic could cause incorrect codegen or encoding behavior.

Overview
Breaking: Removes __runtime_mem_id and __encoding_mem_id in favor of __mem_repr_eq<T>(repr_a: str, repr_b: str) -> bool, which compares structural memory layouts at compile time for "runtime", "encoding", and "hashing" (the string literals are not emitted to bytecode).

The compiler no longer hashes representations to opaque u64s; encoding and hashing both use the renamed packed representation logic (get_packed_representation), while runtime layout is unchanged. Type-checking now requires two compile-time str literals with validated kinds, with a new IntrinsicUnsupportedArgValue diagnostic; several intrinsic error messages are normalized to use the __name form.

std and generated ABI encode/decode / tuple is_*_trivial checks switch from comparing mem IDs to __mem_repr_eq::<Self>("runtime", "encoding"); tuple hashing triviality uses "runtime" vs "hashing". Docs add the new intrinsic; E2E intrinsics tests are consolidated under language/intrinsics with pass/fail coverage for __mem_repr_eq.

Reviewed by Cursor Bugbot for commit 307ac1e. Bugbot is set up for automated code reviews on this repo. Configure here.

@ironcev
ironcev temporarily deployed to fuel-sway-bot July 24, 2026 08:38 — with GitHub Actions Inactive
@ironcev ironcev added compiler General compiler. Should eventually become more specific as the issue is triaged compiler: ir IRgen and sway-ir including optimization passes breaking May cause existing user code to break. Requires a minor or major release. labels Jul 24, 2026
@ironcev

ironcev commented Jul 24, 2026

Copy link
Copy Markdown
Member Author

👍

@codspeed

codspeed Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 25 untouched benchmarks


Comparing ironcev/mem-repr-id-intrinsics (307ac1e) with master (0cd3db3)

Open in CodSpeed

@ironcev
ironcev temporarily deployed to fuel-sway-bot July 25, 2026 14:43 — with GitHub Actions Inactive
@ironcev ironcev changed the title Implement __mem_rep_id intrinsics Implement __mem_rep_eq intrinsic Jul 25, 2026
@ironcev
ironcev temporarily deployed to fuel-sway-bot July 25, 2026 15:10 — with GitHub Actions Inactive
@ironcev
ironcev temporarily deployed to fuel-sway-bot July 25, 2026 15:12 — with GitHub Actions Inactive
@ironcev
ironcev marked this pull request as ready for review July 25, 2026 15:58
@ironcev
ironcev requested review from a team as code owners July 25, 2026 15:58
@ironcev
ironcev enabled auto-merge (squash) July 25, 2026 15:59
@ironcev ironcev changed the title Implement __mem_rep_eq intrinsic Implement __mem_repr_eq intrinsic Jul 26, 2026
@ironcev
ironcev merged commit cd52fcc into master Jul 27, 2026
47 checks passed
@ironcev
ironcev deleted the ironcev/mem-repr-id-intrinsics branch July 27, 2026 12:21

This branch was previously deployed

1 inactive deployment
fuel-sway-bot — 307ac1e3 Deployed Jul 25, 2026 by ironcev via forc-run-benchmarks #27098
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking May cause existing user code to break. Requires a minor or major release. compiler: ir IRgen and sway-ir including optimization passes compiler General compiler. Should eventually become more specific as the issue is triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants