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

Type inference with Numeric and generic function parameters causes Internal Compiler Error #6215

Open
ironcev opened this issue Jul 3, 2024 · 0 comments
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler General compiler. Should eventually become more specific as the issue is triaged

Comments

@ironcev
Copy link
Member

ironcev commented Jul 3, 2024

Compiling this code will (as expected) generate an ICE:

script;

fn main() -> u8 {
    let x = 123;
    fn_with_generic_arg(x);
    x
}

fn fn_with_generic_arg<T>(_arg: T) { }
ICE: Verification failed: Type mismatch found for call to 'fn_with_generic_arg_0': u8 is not a u64.

As expected, because the ICE is caused by the way we do type inference, monomorphization and Numeric decay. I doubt we can do something about it without changing our type inference mechanism to solve the type equation looking at the usages within the whole scope.

What happens here is the following. In let x = 123;, x starts as Unkonwn and gets turned into Numeric. The UnknownGeneric T gets then also unified into Numeric and since monomorphisation needs it to be a concrete integer, Numeric decay will turn it into u64. x will still be Numeric. In the final explicit return, x will be unified with the function result and become u8.

Thus, we will end up in the fn_with_generic_arg accepting u64 and x being u8 and passed to the function. Generated IR, as expected, shows that:

script {
    entry fn main() -> u8, !1 {
        local u8 x

        entry():
        v0 = get_local ptr u8, x, !2
        v1 = const u8 123, !3
        store v1 to v0, !2
        v2 = get_local ptr u8, x, !4
        v3 = load v2
        v4 = call fn_with_generic_arg_0(v3), !5
        v5 = get_local ptr u8, x, !6
        v6 = load v5
        ret u8 v6
    }

    fn fn_with_generic_arg_0(_arg !7: u64) -> (), !8 {
        entry(_arg: u64):
        v0 = const unit ()
        ret () v0
    }
}
@ironcev ironcev added bug Something isn't working compiler General compiler. Should eventually become more specific as the issue is triaged compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen labels Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler General compiler. Should eventually become more specific as the issue is triaged
Projects
None yet
Development

No branches or pull requests

1 participant