Skip to content
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Compiler/Driver/CompilerDiagnostics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,12 @@ type Exception with
if ty1 <> ty2 + tpcs then
os.AppendString(ErrorFromAddingTypeEquation2E().Format ty1 ty2 tpcs)

let e =
match e with
| ConstraintSolverTypesNotInEqualityRelation(env, ty1b, ty2b, m, m2, contextInfo) when typeEquiv g ty2 ty2b ->
ConstraintSolverTypesNotInEqualityRelation(env, ty2b, ty1b, m, m2, contextInfo)
| _ -> e

e.Output(os, suggestNames)

| ErrorFromApplyingDefault(_, denv, _, defaultType, e, _) ->
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Symbols/FSharpDiagnostic.fs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str
| Some symbolEnv ->

match diagnostic.Exception with
| ErrorFromAddingConstraint(displayEnv, ConstraintSolverTypesNotInEqualityRelation(_, actualType, expectedType, _, _, contextInfo), _)
| ErrorFromAddingTypeEquation(_, displayEnv, expectedType, actualType, ConstraintSolverTupleDiffLengths(contextInfo = contextInfo), _)
| ErrorsFromAddingSubsumptionConstraint(_, displayEnv, expectedType, actualType, _, contextInfo, _) ->
let context = DiagnosticContextInfo.From(contextInfo)
Expand All @@ -187,6 +188,8 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str
ty1, ty2
elif not (typeEquiv g ty1 ty2) then
ty1, ty2
elif typeEquiv g ty1 ty2b then
ty1b, ty2b
else ty2b, ty1b

let context = DiagnosticContextInfo.From(contextInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ module RecordTypes =
(Warning 464, Line 15, Col 22, Line 15, Col 28, "This code is less generic than indicated by its annotations. A unit-of-measure specified using '_' has been determined to be '1', i.e. dimensionless. Consider making the code generic, or removing the use of '_'.")
(Warning 464, Line 15, Col 35, Line 15, Col 42, "This code is less generic than indicated by its annotations. A unit-of-measure specified using '_' has been determined to be '1', i.e. dimensionless. Consider making the code generic, or removing the use of '_'.")
(Error 5, Line 17, Col 1, Line 17, Col 5, "This field is not mutable")
(Error 1, Line 17, Col 16, Line 17, Col 22, "The type 'decimal<Kg>' does not match the type 'float<Kg>'")
(Error 1, Line 17, Col 16, Line 17, Col 22, "The type 'float<Kg>' does not match the type 'decimal<Kg>'")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's simplify this case a bit to

Image

The situation is similar here, the expected type is explicitly specified and is decimal<Kg>, but the error message threats it as the actual type.

Also note that the error range is on the second argument, not on the operator. This is due to the fact that in the error
ErrorFromAddingTypeEquation(...ConstraintSolverTypesNotInEqualityRelation(...m1), m2)the wrong m is taken. But I would fix it in a separate PR.

(Error 5, Line 18, Col 1, Line 18, Col 5, "This field is not mutable")
(Error 1, Line 18, Col 16, Line 18, Col 21, "This expression was expected to have type\n 'float' \nbut here has type\n 'decimal' ")
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ module StaticAbstractBug =
|> compile
|> shouldFail
|> withDiagnostics [
(Error 1, Line 14, Col 41, Line 14, Col 42, "The type 'bool' does not match the type 'int'")
(Error 1, Line 14, Col 41, Line 14, Col 42, "The type 'int' does not match the type 'bool'")
(Error 1, Line 16, Col 32, Line 16, Col 33, "This expression was expected to have type
Comment on lines -1148 to 1149
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

Here expected = int, actual = bool, which is incorrect. Just two lines below is a similar case, where expected = bool is correct.

'bool'
but here has type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ let inline checkDiagnosticData
(check: 'a -> unit)
(checkResults: 'b when 'b: (member Diagnostics: FSharpDiagnostic[])) =
match checkResults.Diagnostics |> Array.tryFind (fun d -> d.ErrorNumber = diagnosticNumber) with
| None -> failwith "Expected diagnostic not found"
| None -> failwith $"Expected diagnostic (number {diagnosticNumber}) not found"
| Some diagnostic ->

Assert.Equal(message, diagnostic.Message)
match diagnostic.ExtendedData with
| Some(:? 'a as data) -> check data
| _ -> failwith "Expected diagnostic extended data not found"

checkResults

[<Fact>]
let ``TypeMismatchDiagnosticExtendedData 01`` () =
Expand Down Expand Up @@ -187,6 +188,46 @@ let f2 (x: inref<'T>) = f1 &x
Assert.Equal("outref<'T>", typeMismatch.ExpectedType.Format(displayContext))
Assert.Equal("inref<'T>", typeMismatch.ActualType.Format(displayContext)))

[<Fact>]
let ``TypeMismatchDiagnosticExtendedData 11`` () =
FSharp """
type T() =
static member P1 = T.P2 + 1
static member P2 = ""
"""
|> typecheckResults
// static member P1 = T.P2 ->+<- 1
|> checkDiagnosticData
(43, "The type 'int' does not match the type 'string'")
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
let displayContext = typeMismatch.DisplayContext
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
Assert.Equal("string", typeMismatch.ExpectedType.Format(displayContext))
Assert.Equal("int", typeMismatch.ActualType.Format(displayContext)))

// static member P2 = ->""<-
|> checkDiagnosticData
(1, "The type 'string' does not match the type 'int'")
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
let displayContext = typeMismatch.DisplayContext
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
Assert.Equal("int", typeMismatch.ExpectedType.Format(displayContext))
Assert.Equal("string", typeMismatch.ActualType.Format(displayContext)))

[<Fact>]
let ``TypeMismatchDiagnosticExtendedData 12`` () =
FSharp """
let x: string = 1 + 1
"""
|> typecheckResults
|> checkDiagnosticData
(1, "The type 'int' does not match the type 'string'")
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
let displayContext = typeMismatch.DisplayContext
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
Assert.Equal("string", typeMismatch.ExpectedType.Format(displayContext))
Assert.Equal("int", typeMismatch.ActualType.Format(displayContext)))

[<Theory>]
[<InlineData true>]
[<InlineData false>]
Expand Down
Loading