Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal Compiler Error: Types size do not match. When using __transmute() with u8. #6874

Closed
K1-R1 opened this issue Jan 31, 2025 · 1 comment
Assignees
Labels
bug Something isn't working triage This issue was opened with a template and needs to be triaged by code owners.

Comments

@K1-R1
Copy link
Member

K1-R1 commented Jan 31, 2025

Related Component

compiler

Problem

impl Add for u8 {
    fn add(self, other: Self) -> Self {
        let res_u64 = __add(
            __transmute::<Self, u64>(self),
            __transmute::<Self, u64>(other),
        );

        let max_u8_u64: u64 = __transmute::<Self, u64>(Self::max());

        if __gt(res_u64, max_u8_u64) {
            if panic_on_overflow_is_enabled() {
                __revert(0)
            } else {
                // overflow enabled
                // res % (Self::max() + 1)
                // TODO: investigate as causing ICE: Types size do not match
                __transmute::<u64, Self>(__mod(res_u64, __add(max_u8_u64, 1))) // <--- Causing ICE
            }
        } else {
            __transmute::<u64, Self>(res_u64)
        }
    }
}

Results in Internal Compiler Error: Types size do not match on forc v0.66.6.
The equivalent code for u16 and u32 does not cause errors.

Steps

  1. git checkout the branch https://github.com/FuelLabs/sway/tree/k1-r1-f4
  2. run cd test/src/in_language_tests/test_programs/math_inline_tests
  3. run forc test

Possible Solution(s)

No response

Notes

u8 is also displaying odd behaviour with __transmute() elsewhere. For example:

const MAX_U8_U64: u64 = __transmute::<u8, u64>(u8::max());

Causes the error: Could not evaluate initializer to a const declaration. Whereas the u16 and u32 equivalents do not error:

const MAX_U32_U64: u64 = __transmute::<u32, u64>(u32::max());
const MAX_U16_U64: u64 = __transmute::<u16, u64>(u16::max());

Installed components

latest  - Up to date
nightly - Up to date
fuelup  - Up to date

active toolchain
----------------
latest-aarch64-apple-darwin (default)
  forc : 0.66.6
    - forc-client
      - forc-deploy : 0.66.6
      - forc-run : 0.66.6
    - forc-crypto : 0.66.6
    - forc-debug : 0.66.6
    - forc-doc : 0.66.6
    - forc-fmt : 0.66.6
    - forc-lsp : 0.66.6
    - forc-tx : 0.66.6
    - forc-wallet : 0.11.1
  fuel-core : 0.40.0
  fuel-core-keygen : 0.40.0
@K1-R1 K1-R1 added bug Something isn't working triage This issue was opened with a template and needs to be triaged by code owners. labels Jan 31, 2025
@xunilrj xunilrj self-assigned this Feb 1, 2025
@xunilrj
Copy link
Contributor

xunilrj commented Feb 1, 2025

This is expected as __transmute only "reinterpret" the bytes of the type. For some internal implementation details u16 and u32 occupy the same space as u64, and we need to allow them to __transmute or the behaviour would be inconsistent with aggregated types containing these types.

This is not the case for u8, which takes only one byte.

We intend to stop raising ICE in these cases. But for the moment, that is what we can do.

But you can implement it like this:

impl Add for u8 {
    fn add(self, other: Self) -> Self {
        let res_u64 = __add(self.as_u64(), other.as_u64()); // __transmute will live inside `as_u64`
        let max_u8_u64 = Self::max().as_u64();

        if __gt(res_u64, max_u8_u64) && panic_on_overflow_is_enabled() {
                __revert(0)
        }

        res_u64.to_be_bytes()[0] // __transmute will live inside `to_be_bytes`
    }
}

@xunilrj xunilrj closed this as completed Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage This issue was opened with a template and needs to be triaged by code owners.
Projects
None yet
Development

No branches or pull requests

2 participants