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

Improve error reporting: Smarter heuristics on incorrect return type of if / else branch #1106

Closed
Tracked by #1103
isaacabraham opened this issue Apr 24, 2016 · 10 comments

Comments

@isaacabraham
Copy link
Contributor

isaacabraham commented Apr 24, 2016

What

If types are incompatible across all branches of an if / else expression, the return type of the first branch is used to determine the "correct" type. Given the following code sample, this behaviour, whilst consistent, is usually not what the user expects: -

let test = 10
let y =
    if test > 10 then "test"
    elif test > 20 then 456
    elif test > 30 then 789
    elif test > 35 then 101010
    else 123

error FS0001: This expression was expected to have type string but here has type int

In this case, all four branches that return an integer are flagged as having an error when it is much more likely that the first branch ("test") is in error.

Why

Changing the first type in a conditional causes all the other cases to break, when in fact it's normally the first one that's in error. A beginner will follow all the error messages raised by the compiler and not realise that they are actually all correct, but in fact the error is located in the one branch that the compiler has not flagged.

How

The compiler should ideally find the most "common" return type and flag that as the correct one and mark the other branch(es) as being in error.

@smoothdeveloper
Copy link
Contributor

Maybe the compiler should list the several types:

error FS0001: The expressions are of inconsistent type: string 1 occurence(s), int 4 occurence(s). Make expression type consistent across all the branches

verbose output can also contain this:

if test > 10 then "test"
__________________^ string
elif test > 20 then 456
____________________^ int
elif test > 30 then 789
____________________^ int
elif test > 35 then 101010
____________________^ int
else 123
_____^ int

@lulu-berlin
Copy link

Similarly to here, I'd like to suggest something like: The types of the values produced in all "then" and "else" branches of a conditional expression must match.

@isaacabraham
Copy link
Contributor Author

I think we can do better than that; just saying they must all match is good, but telling the user what the current branches are and what one should be changed is better.

@lulu-berlin
Copy link

Trying again: The types of the values produced in all "then" (string, int, int, int) and "else" (int) branches of a conditional expression are expected to match. Make expression type consistent across all branches

@isaacabraham
Copy link
Contributor Author

See my comment in the other issue - splitting up by "then" and "else" doesn't (IMHO) make much sense. Easier just to say "all branches (string, int)" etc. I think?

@lulu-berlin
Copy link

@isaacabraham, I agree - but as I commented on #1105, I think it makes sense to mention the existence of the "then" and "else" branches without spliting the type listing.

@forki
Copy link
Contributor

forki commented May 3, 2016

#1142 already gives:

image

I think this is already pretty good.

@forki
Copy link
Contributor

forki commented May 3, 2016

A little background: the type checker is adding type unification formulas basically expression by expression. The first formula that introduces a conflict will be reported. At this point we don't have enough TAST information to make assumptions about the other branches. I vote to close this specific request since the error message is already better than before and I don't see a way to improve that as described here without changing the design of the type checker.

@dsyme
Copy link
Contributor

dsyme commented May 3, 2016

Yes, it's very hard to vote across the different branches. I will close this specific suggestion.

@dsyme dsyme closed this as completed May 3, 2016
@isaacabraham
Copy link
Contributor Author

I suspected that this would be the case - it's good that we've looked into this though and understand why it's not appropriate. Perhaps this can be revisited another time :-)

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

No branches or pull requests

5 participants