Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
35 changes: 19 additions & 16 deletions src/Compiler/Driver/CompilerDiagnostics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -733,21 +733,15 @@ type Exception with
if m.StartLine <> m2.StartLine then
os.AppendString(SeeAlsoE().Format(stringOfRange m))

| ConstraintSolverTypesNotInEqualityRelation(denv, (TType_measure _ as ty1), (TType_measure _ as ty2), m, m2, _) ->
// REVIEW: consider if we need to show _cxs (the type parameter constraints)
let ty1, ty2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2

os.AppendString(ConstraintSolverTypesNotInEqualityRelation1E().Format ty1 ty2)

if m.StartLine <> m2.StartLine then
os.AppendString(SeeAlsoE().Format(stringOfRange m))

| ConstraintSolverTypesNotInEqualityRelation(denv, ty1, ty2, m, m2, contextInfo) ->
// REVIEW: consider if we need to show _cxs (the type parameter constraints)
let ty1, ty2, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2
let ty1str, ty2str, _cxs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2

OutputTypesNotInEqualityRelationContextInfo contextInfo ty1 ty2 m os (fun _ ->
os.AppendString(ConstraintSolverTypesNotInEqualityRelation2E().Format ty1 ty2))
match ty1, ty2 with
| TType_measure _, TType_measure _ -> os.AppendString(ConstraintSolverTypesNotInEqualityRelation1E().Format ty1str ty2str)
| _ ->
OutputTypesNotInEqualityRelationContextInfo contextInfo ty1str ty2str m os (fun _ ->
os.AppendString(ConstraintSolverTypesNotInEqualityRelation2E().Format ty1str ty2str))

if m.StartLine <> m2.StartLine then
os.AppendString(SeeAlsoE().Format(stringOfRange m))
Expand Down Expand Up @@ -816,11 +810,20 @@ type Exception with
os.AppendString(SeeAlsoE().Format(stringOfRange m1))

| ErrorFromAddingTypeEquation(g, denv, ty1, ty2, e, _) ->
if not (typeEquiv g ty1 ty2) then
let ty1, ty2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2
let e =
if not (typeEquiv g ty1 ty2) then
let ty1, ty2, tpcs = NicePrint.minimalStringsOfTwoTypes denv ty1 ty2

if ty1 <> ty2 + tpcs then
os.AppendString(ErrorFromAddingTypeEquation2E().Format ty1 ty2 tpcs)
if ty1 <> ty2 + tpcs then
os.AppendString(ErrorFromAddingTypeEquation2E().Format ty1 ty2 tpcs)

e

else
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)

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>'")
(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
'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,7 +188,62 @@ let f2 (x: inref<'T>) = f1 &x
Assert.Equal("outref<'T>", typeMismatch.ExpectedType.Format(displayContext))
Assert.Equal("inref<'T>", typeMismatch.ActualType.Format(displayContext)))

[<Theory>]
[<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)))

[<Fact>]
let ``TypeMismatchDiagnosticExtendedData 13`` () =
FSharp """
let x: string -> string = id
let y: unit -> string = x
"""
|> typecheckResults
|> checkDiagnosticData
(1, "Type mismatch. Expecting a\n 'unit -> string' \nbut given a\n 'string -> string' \nThe type 'string' does not match the type 'unit'")
(fun (typeMismatch: TypeMismatchDiagnosticExtendedData) ->
let displayContext = typeMismatch.DisplayContext
Assert.Equal(DiagnosticContextInfo.NoContext, typeMismatch.ContextInfo)
Assert.Equal("unit -> string", typeMismatch.ExpectedType.Format(displayContext))
Assert.Equal("string -> string", typeMismatch.ActualType.Format(displayContext)))

[<Theory>]
[<InlineData true>]
[<InlineData false>]
let ``ArgumentsInSigAndImplMismatchExtendedData 01`` useTransparentCompiler =
Expand Down
Loading