elm / compiler

Compiler for Elm, a functional language for reliable webapps.
https://elm-lang.org/
BSD 3-Clause "New" or "Revised" License
7.51k stars 656 forks source link

Error message oddity for types #2204

Open jfmengels opened 3 years ago

jfmengels commented 3 years ago

Quick Summary: A weird error message is displayed when there is a type mismatch with an empty destructuring pattern.

SSCCE

In the following example, the type for the argument is wrong

func : Int -> Int
func {} =
    1

Resulting in the following error message:

The 1st argument to `func` is weird.

1323| func {} =
           ^^
The argument is a pattern that matches record values of type:

    { a  }

But the type annotation on `func` says the 1st argument should be:

    Int

But { a } is not a syntactically valid type annotation, making this compiler error a bit weird.

Additional Details/thoughts

The compiler has a hard time figuring what the type should be. If the parameter was not destructured, the suggested type would be a. If the parameter was destructured as {b}, the suggested type would be { a | b : b }.

But there is no way in Elm's type system and syntax to properly describe what the type of {} could be.

Here are some of the approaches I see that could be taken:

  1. Suggest {}. While this would be correct, this would also be too limitative.

  2. Suggest a, and have the language consider anything destructured as {} to be valid Elm code. I guess it could be considered like "extracting no fields from this value", which could be considered valid in all cases? :man_shrugging:. A side-effect of this would be that {} would in a way be considered as a wild card in a case expression pattern.

  3. Change the error message for this specific case to be more tailored to this problem. I imagine you'd also have to do the same thing for nested destructuring like func (A {}) = 1

  4. Make {} in a pattern invalid Elm code. That would be a breaking change, but I think this would be reasonable (for 0.20 or another future breaking version). A nice parsing error to accompany this would be be :ok_hand:

My personal opinion is that 4 would be the way to go. While 1, 2 and 3 would solve the problem, they would not solve it for other tooling. For instance, IDEs that support Elm often have a "Add type annotation" feature. Should they encounter func {} = 1, then they would also have to resolve this tricky problem. If this was made into invalid Elm code, then they would not have to worry about this code (and I guess go for solution 1).

Also, I have just patched elm-syntax to support parsing empty records in patterns, and have a ongoing PR to support those in IntelliJ. In other words, parsing empty records in pattern is to start off badly supported.

github-actions[bot] commented 3 years ago

Thanks for reporting this! To set expectations:

Finally, please be patient with the core team. They are trying their best with limited resources.