Inconistent and confusing error reporting for `else` branch in CE
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 131
Description
I'm aware of https://github.com/dotnet/fsharp/issues/1103 and I mostly liked the changes. It even seems like now I even expect good error messages for some common errors, one (IMHO) particularly useful is:
```fsharp
let testHandler =
if 1 = 2 then
raise <| exn("test")
else
if 2 = 3 then
3
else
if 2 = 3 then
failwithf "some other"
else
"test" // FS0001 All branches of an 'if' expression must return values of the same type as the first branch, which here is 'int'. This branch returns a value of type 'string'
```
Now consider you have the following code (which compiles fine):
```fsharp
let testHandler =
if 1 = 2 then
raise <| exn("test")
else
if 2 = 3 then
failwithf "some other"
else
"test"
```
And assume you refactor this into an asynchronous (for example task based) function:
```fsharp
let testHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
if 1 = 2 then
raise <| exn("test")
else
if 2 = 3 then
failwithf "some other"
else
let! d = Task.Delay 100
return "test" // FS0001 This expression was expected to have type 'unit' but here it has type 'string'
}
```
As newcomers have no longer the ability to learn "reading" this compiler error they have no way of figuring out what the compiler is trying to tell them.
/cc @forki
**Expected behavior**
Make sure to have at least a friendly error here. (I'm not too worried about the code not compiling)
**Actual behavior**
Cryptic error message
**Known workarounds**
When you add a type hint it improves a bit (at least the correct lines are underlined):
```fsharp
let testHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
task {
if 1 = 2 then
raise <| exn("test") // FS0001 Type mismatch. Expecting a 'FSharp.Control.Tasks.TaskBuilder.Step' but given a 'FSharp.Control.Tasks.TaskBuilder.Step' The type 'string' does not match the type 'unit'
else
if 2 = 3 then
failwithf "some other" // FS0001 Type mismatch. Expecting a 'FSharp.Control.Tasks.TaskBuilder.Step' but given a 'FSharp.Control.Tasks.TaskBuilder.Step' The type 'string' does not match the type 'unit'
else
let! d = Task.Delay 100
return "test"
} : Task
```
But you still are a bit confused about what `FSharp.Control.Tasks.TaskBuilder.Step` is.
**Related information**
Provide any related information (optional):
* Operating system: Win10
* .NET Runtime kind: All
* Editing Tools: Latest VS 2019
Contributor guide
Assessment
This issue has not been assessed yet.