Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

* 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))
* 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))
* TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851))

### Changed
* Use `errorR` instead of `error` in `CheckDeclarations.fs` when possible. ([PR #18645](https://github.com/dotnet/fsharp/pull/18645))
Expand Down
14 changes: 11 additions & 3 deletions src/Compiler/Symbols/FSharpDiagnostic.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace FSharp.Compiler.Diagnostics

open System

open FSharp.Compiler.AttributeChecking
open FSharp.Compiler.CheckExpressions
open FSharp.Compiler.ConstraintSolver
open FSharp.Compiler.SignatureConformance
Expand All @@ -26,7 +25,6 @@ open FSharp.Compiler.CompilerDiagnostics
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.DiagnosticsLogger
open FSharp.Compiler.Text
open FSharp.Compiler.Text.Position
open FSharp.Compiler.Text.Range

module ExtendedData =
Expand Down Expand Up @@ -199,11 +197,21 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str

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

| ErrorFromAddingTypeEquation(g, displayEnv, ty1, ty2, ConstraintSolverTypesNotInEqualityRelation(_, ty1b, ty2b, _, _, contextInfo), _) ->
let expectedType, actualType =
if typeEquiv g ty1 ty1b && typeEquiv g ty2 ty2b then
ty1, ty2
elif not (typeEquiv g ty1 ty2) then
ty1, ty2
else ty2b, ty1b

let context = DiagnosticContextInfo.From(contextInfo)
Some(TypeMismatchDiagnosticExtendedData(symbolEnv, displayEnv, expectedType, actualType, context))

| ErrorFromAddingTypeEquation(_, displayEnv, expectedType, actualType, _, _)->
Some(TypeMismatchDiagnosticExtendedData(symbolEnv, displayEnv, expectedType, actualType, DiagnosticContextInfo.NoContext))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
open FSharp.Compiler.Text
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.Diagnostics.ExtendedData
open FSharp.Test
open FSharp.Test.Compiler
open Xunit

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

[<Fact>]
let ``TypeMismatchDiagnosticExtendedData 08`` () =
FSharp """
type R = { Field1: int }
let f (x: R) = "" + x.Field1
"""
|> typecheckResults
|> checkDiagnostic
(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)))

[<Fact>]
let ``TypeMismatchDiagnosticExtendedData 09`` () =
FSharp """
let x: string = 1
"""
|> typecheckResults
|> checkDiagnostic
(1, "This expression was expected to have type\n 'string' \nbut here has type\n 'int' ")
(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)))

[<Fact>]
let ``TypeMismatchDiagnosticExtendedData 10`` () =
FSharp """
let f1 (x: outref<'T>) = 1
let f2 (x: inref<'T>) = f1 &x
"""
|> typecheckResults
|> checkDiagnostic
(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'")
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
let displayContext = typeMismatch.DisplayContext
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
Assert.Equal("outref<'T>", typeMismatch.ExpectedType.Format(displayContext))
Assert.Equal("inref<'T>", typeMismatch.ActualType.Format(displayContext)))

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