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

Poor error message in polymorphic tail type error #1316

Closed
matthew-healy opened this issue May 24, 2023 · 0 comments · Fixed by #1320
Closed

Poor error message in polymorphic tail type error #1316

matthew-healy opened this issue May 24, 2023 · 0 comments · Fixed by #1320

Comments

@matthew-healy
Copy link
Contributor

Describe the bug

The following program:

let f : forall r. (forall p. [| 'blo, 'ble ; r |] -> [| 'bla, 'bli; p |]) =
  match { 'blo => 'bla, 'ble => 'bli, _ => 'blo } 
in f 'bli

raises a type error:

error: incompatible types
  ┌─ repl-input-0:2:44
  │
2 │   match { 'blo => 'bla, 'ble => 'bli, _ => 'blo } 
  │                                            ^^^^ this expression
  │
  = Expected an expression of type `a`
  = Found an expression of type `[| 'blo ; _erows_a |]`
  = These types are not compatible

The type a here is pulled out of thin air. What the error is really trying to say is that this function body should be valid for any tail p, including those that don't include the variant 'blo. We should improve the error message in this specific case to make that clearer.

Additional context

Note that record tails exhibit similar behaviour. E.g. in the program:

let f : forall r p { blo: String, ble: Number ; r } -> { bla: String, bli: Number ; p } =
  fun { blo, ble, .. } =>
    { bla = blo, bli = ble }
in f { blo = "", ble = 0 }

where the error message is:

error: incompatible types
  ┌─ repl-input-3:3:5
  │
3 │     { bla = blo, bli = ble }
  │     ^^^^^^^^^^^^^^^^^^^^^^^^ this expression
  │
  = Expected an expression of type `a`
  = Found an expression of type `{  }`
  = These types are not compatible
matthew-healy pushed a commit that referenced this issue May 25, 2023
Previously, if we had a type whose return value contained a polymorphic
tail and we tried to return a value which was not statically known
to be in the return type, we would see a type mismatch error with an
"invented" type name (e.g. `a`) to represent "an arbitrary type in the
tail".

This made it unclear where the problem was, and didn't give any real
direction on how to fix the problem.

This commit raises a specific error in this case, which informs users
that the type they've tried to return is not guaranteed to exist in the
polymorphic tail. We also now pass around a var kind with type errors
related to constant mismatches, so we can print a representation of the
tail type (e.g. `[| ; x |]`) instead of inventing phantom type names
for errors.

Fixes #1316.
matthew-healy pushed a commit that referenced this issue May 25, 2023
Previously, if we had a type whose return value contained a polymorphic
tail and we tried to return a value which was not statically known
to be in the return type, we would see a type mismatch error with an
"invented" type name (e.g. `a`) to represent "an arbitrary type in the
tail".

This made it unclear where the problem was, and didn't give any real
direction on how to fix the problem.

This commit raises a specific error in this case, which informs users
that the type they've tried to return is not guaranteed to exist in the
polymorphic tail. We also now pass around a var kind with type errors
related to constant mismatches, so we can print a representation of the
tail type (e.g. `[| ; x |]`) instead of inventing phantom type names
for errors.

Fixes #1316.
matthew-healy pushed a commit that referenced this issue May 25, 2023
Previously, if we had a type whose return value contained a polymorphic
tail and we tried to return a value which was not statically known
to be in the return type, we would see a type mismatch error with an
"invented" type name (e.g. `a`) to represent "an arbitrary type in the
tail".

This made it unclear where the problem was, and didn't give any real
direction on how to fix the problem.

This commit raises a specific error in this case, which informs users
that the type they've tried to return is not guaranteed to exist in the
polymorphic tail. We also now pass around a var kind with type errors
related to constant mismatches, so we can print a representation of the
tail type (e.g. `[| ; x |]`) instead of inventing phantom type names
for errors.

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

Successfully merging a pull request may close this issue.

1 participant