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

Better type check error messages for expressions involving polymorphic functions #466

Open
sharkdp opened this issue Jun 12, 2024 · 2 comments

Comments

@sharkdp
Copy link
Owner

sharkdp commented Jun 12, 2024

We try to avoid showing constraint-solver error messages wherever we can, because they will probably always be worse than direct type-checker errors. Unfortunately, there are still some cases where they show up. A simplified example looks like this:

>>> fn id(x) = x

  fn id<A>(x: A) -> A = x

>>> 1 meter + id(1 second)
error: Could not solve the following constraints:
  Length / Time = Scalar
.. while trying to infer types in the (elaborated) statement:
  1 metre + id(1 second)

 = Consider adding type annotations to get more precise error messages.

Here, we instantiate id :: T0 -> T0 with a fresh type variable T0, add a Time ~ T0 constraint for the argument, and a Length ~ T0 constraint for the return type. But we fail to stop immediately and instead go into the constraint solver stage where those two constraints are turned into a single Length ~ Time and subsequently into a Length / Time = Scalar dtype constraint, which can not be solved.

@rben01
Copy link
Contributor

rben01 commented Sep 22, 2024

So in the provided example, the goal is to be able to go back and attach the constraint solver error to the + (which must have two arguments of the same type)? Or more concretely, to develop heuristics about which generic parameter unifications should have highest precedence? i.e., that f<A>(x: A) -> A should be solved earlier in the constraint solving process than add<A>(x: A, y: A) -> A because it is “more deterministic” — although I'm having trouble articulating exactly how (bottom up vs. top down?). It seems like one simple heuristic (that needs verification) is that unifying an input generic parameter with an output generic parameter should take higher precedence than unifying two input generic parameters. Perhaps also that constraints should be solved in the order that the expressions would be evaluated (the latest expression to be evaluated should have its constraints’ failures be the ones reported).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants