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

[Bug][move-compiler-v2] Function-valued argument type error message is confusing #14681

Open
brmataptos opened this issue Sep 18, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@brmataptos
Copy link
Contributor

🐛 Bug

    public inline fun pass_mut_ref<T>(v: &mut vector<T>, action: |&mut T|&mut T): &mut T {
        action(vector::borrow_mut(v, 0))
    }

    public fun consume_mut_freeze() {
        let v = vector[1, 2, 3];
        let r = pass_mut_ref(&mut v, |x| (freeze(x)));
    }

yields the error message:

error: the function takes `&mut` but `&` was provided
   ┌─ tests/checking/typing/lambda_widen_result.move:43:38
   │
43 │         let r = pass_mut_ref(&mut v, |x| (freeze(x)));
   │                                      ^^^^^^^^^^^^^^^

Which is very confusing. The problem here is that

  • The type of parameter action is |&mut T|&mut T.
  • The value provided is a lambda of ambiguous type, either |&mut T|&T or |&T|&T.
  • So the type checker is trying to unify |&mut T|&T with |&mut T|&mut T and finds that the
    return type &T is not compatible with &mut T.
  • But:
    • saying that "the function takes &mut" is wrong: it takes a function value with result type &mut.
    • No & was provided: rather, a function value with result type & was provided.
  • BTW, the type checker probably tries both parameter types and gets one right.

For the parameter type of the function-valued parameter, it's difficult to engineer a similar situation without PR #14254, which adds type declarations for lambda parameters.

But changing the test case to

    public fun consume_mut_mut() {
        let v = vector[1, 2, 3];
        let r = pass_mut_ref(&mut v, |a, b| a);
    }

leads to the more reasonable error message:

error: cannot pass `|(_, _)|_` to a function which expects argument of type `|&mut integer|&mut integer`
   ┌─ tests/checking/typing/lambda_widen_result.move:28:38
   │
28 │         let r = pass_mut_ref(&mut v, |a, b| a);
   │                                      ^^^^^^^^

which would be better for the result case.

@brmataptos brmataptos added the bug Something isn't working label Sep 18, 2024
@brmataptos
Copy link
Contributor Author

@rahxephon89 and @wrwg this is Urgent because I will need this cleaned up for more general-purpose lambda parameters. I've spent a few minutes looking at the code, and hope one of you can give some insight into how to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: 🆕 New
Development

No branches or pull requests

1 participant