Skip to content

Commit 6a1e4af

Browse files
authored
TypeMismatchDiagnosticExtendedData: fix expected type calculation (#18851)
1 parent 934a248 commit 6a1e4af

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

docs/release-notes/.FSharp.Compiler.Service/10.0.100.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
* Fix SRTP nullness constraint resolution for types imported from older assemblies. AmbivalentToNull types now use legacy F# nullness rules instead of always satisfying `'T : null` constraints. ([Issue #18390](https://github.com/dotnet/fsharp/issues/18390), [Issue #18344](https://github.com/dotnet/fsharp/issues/18344))
2323
* Fix Show XML doc for enum fields in external metadata ([Issue #17939](https://github.com/dotnet/fsharp/issues/17939#issuecomment-3137410105), [PR #18800](https://github.com/dotnet/fsharp/pull/18800))
24+
* TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851))
2425

2526
### Changed
2627
* Use `errorR` instead of `error` in `CheckDeclarations.fs` when possible. ([PR #18645](https://github.com/dotnet/fsharp/pull/18645))

src/Compiler/Symbols/FSharpDiagnostic.fs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,21 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str
170170

171171
match diagnostic.Exception with
172172
| ErrorFromAddingTypeEquation(_, displayEnv, expectedType, actualType, ConstraintSolverTupleDiffLengths(contextInfo = contextInfo), _)
173-
| ErrorFromAddingTypeEquation(_, displayEnv, expectedType, actualType, ConstraintSolverTypesNotInEqualityRelation(_, _, _, _, _, contextInfo), _)
174173
| ErrorsFromAddingSubsumptionConstraint(_, displayEnv, expectedType, actualType, _, contextInfo, _) ->
175174
let context = DiagnosticContextInfo.From(contextInfo)
176175
Some(TypeMismatchDiagnosticExtendedData(symbolEnv, displayEnv, expectedType, actualType, context))
177176

177+
| ErrorFromAddingTypeEquation(g, displayEnv, ty1, ty2, ConstraintSolverTypesNotInEqualityRelation(_, ty1b, ty2b, _, _, contextInfo), _) ->
178+
let expectedType, actualType =
179+
if typeEquiv g ty1 ty1b && typeEquiv g ty2 ty2b then
180+
ty1, ty2
181+
elif not (typeEquiv g ty1 ty2) then
182+
ty1, ty2
183+
else ty2b, ty1b
184+
185+
let context = DiagnosticContextInfo.From(contextInfo)
186+
Some(TypeMismatchDiagnosticExtendedData(symbolEnv, displayEnv, expectedType, actualType, context))
187+
178188
| ErrorFromAddingTypeEquation(_, displayEnv, expectedType, actualType, _, _)->
179189
Some(TypeMismatchDiagnosticExtendedData(symbolEnv, displayEnv, expectedType, actualType, DiagnosticContextInfo.NoContext))
180190

tests/FSharp.Compiler.ComponentTests/ErrorMessages/ExtendedDiagnosticDataTests.fs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
open FSharp.Compiler.Text
55
open FSharp.Compiler.Diagnostics
66
open FSharp.Compiler.Diagnostics.ExtendedData
7-
open FSharp.Test
87
open FSharp.Test.Compiler
98
open Xunit
109

@@ -144,6 +143,50 @@ if true then 1 else "a"
144143
Assert.Equal("int", typeMismatch.ExpectedType.Format(displayContext))
145144
Assert.Equal("string", typeMismatch.ActualType.Format(displayContext)))
146145

146+
[<Fact>]
147+
let ``TypeMismatchDiagnosticExtendedData 08`` () =
148+
FSharp """
149+
type R = { Field1: int }
150+
let f (x: R) = "" + x.Field1
151+
"""
152+
|> typecheckResults
153+
|> checkDiagnostic
154+
(1, "The type 'int' does not match the type 'string'")
155+
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
156+
let displayContext = typeMismatch.DisplayContext
157+
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
158+
Assert.Equal("string", typeMismatch.ExpectedType.Format(displayContext))
159+
Assert.Equal("int", typeMismatch.ActualType.Format(displayContext)))
160+
161+
[<Fact>]
162+
let ``TypeMismatchDiagnosticExtendedData 09`` () =
163+
FSharp """
164+
let x: string = 1
165+
"""
166+
|> typecheckResults
167+
|> checkDiagnostic
168+
(1, "This expression was expected to have type\n 'string' \nbut here has type\n 'int' ")
169+
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
170+
let displayContext = typeMismatch.DisplayContext
171+
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
172+
Assert.Equal("string", typeMismatch.ExpectedType.Format(displayContext))
173+
Assert.Equal("int", typeMismatch.ActualType.Format(displayContext)))
174+
175+
[<Fact>]
176+
let ``TypeMismatchDiagnosticExtendedData 10`` () =
177+
FSharp """
178+
let f1 (x: outref<'T>) = 1
179+
let f2 (x: inref<'T>) = f1 &x
180+
"""
181+
|> typecheckResults
182+
|> checkDiagnostic
183+
(1, "Type mismatch. Expecting a\n 'outref<'T>' \nbut given a\n 'inref<'T>' \nThe type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'")
184+
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
185+
let displayContext = typeMismatch.DisplayContext
186+
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
187+
Assert.Equal("outref<'T>", typeMismatch.ExpectedType.Format(displayContext))
188+
Assert.Equal("inref<'T>", typeMismatch.ActualType.Format(displayContext)))
189+
147190
[<Theory>]
148191
[<InlineData true>]
149192
[<InlineData false>]

0 commit comments

Comments
 (0)