You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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).
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
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
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
breakingMay cause existing user code to break. Requires a minor or major release.compiler: irIRgen and sway-ir including optimization passescompilerGeneral compiler. Should eventually become more specific as the issue is triaged
2 participants
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.
Description
This PR introduces a new
__mem_repr_eqintrinsic for comparing memory representation of types, and removes the existing__runtime_mem_idand__encoding_mem_idintrinsics.We decided to introduce
__mem_repr_eqto mitigate the following issues we had with existing intrinsics:mem_ids wereu64values computed usingDefaultHasherwhose results are not guaranteed to be stable across different runs of the same Sway compiler or being same on different target architectures.u64was 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_eqis defined as:It returns
trueif the memory representationrepr_aof the typeTis equal to its memory representationrepr_b, assumingThas both memory representations. IfTdoes not have any of the representationsrepr_aorrepr_b, returnsfalse.The valid values for
repr_aandrepr_bare"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 likeVecorraw_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 implementingis_hash_trivial#7695. Not all types have a canonical hashing defined, e.g., dynamic types likeVecorraw_slice. In that case,"hashing"never compares equal to any other memory representation, including to itself.To test if a type
Thas"encoding"or"hashing"memory representation defined, compare that representation to itself. E.g.:let has_encoding_repr = __mem_repr_eq<T>("encoding", "encoding");repr_aandrepr_bmust be compile-time constantstrs, whose values are one of"runtime","encoding", or"hashing". The constantstrs never end up in the bytecode.Additionally, the PR moves existing E2E intrinsics tests that were not in the
language/intrinsicsintolanguage/intrinsics.Breaking Change
The old
__runtime_mem_idand__encoding_mem_idintrinsics are removed. The code that is using them must switch to the new__mem_repr_eq.Checklist
Breaking*orNew Featurelabels where relevant.