From b4805cd8c92c530bfcd1a118e17c6ec2d2d28a50 Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Mon, 25 Sep 2023 16:56:29 +0200 Subject: [PATCH 1/3] Try TcExprFlex Seems like it could be done better, right now there are two type checking passes for same expression --- src/Compiler/Checking/CheckComputationExpressions.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs index e27dcffc7bf..82403341f7d 100644 --- a/src/Compiler/Checking/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/CheckComputationExpressions.fs @@ -2210,7 +2210,7 @@ let TcSequenceExpression (cenv: cenv) env tpenv comp (overallTy: OverallTy) m = let env = { env with eContextInfo = ContextInfo.SequenceExpression genOuterTy } - if enableImplicitYield then + if enableImplicitYield then let hasTypeUnit, expr, tpenv = TryTcStmt cenv env tpenv comp if hasTypeUnit then Choice2Of2 expr, tpenv @@ -2218,6 +2218,7 @@ let TcSequenceExpression (cenv: cenv) env tpenv comp (overallTy: OverallTy) m = let genResultTy = NewInferenceType g let mExpr = expr.Range UnifyTypes cenv env mExpr genOuterTy (mkSeqTy cenv.g genResultTy) + let expr, tpenv = TcExprFlex cenv flex true genResultTy env tpenv comp let exprTy = tyOfExpr cenv.g expr AddCxTypeMustSubsumeType env.eContextInfo env.DisplayEnv cenv.css mExpr NoTrace genResultTy exprTy let resExpr = mkCallSeqSingleton cenv.g mExpr genResultTy (mkCoerceExpr(expr, genResultTy, mExpr, exprTy)) From bf36f6155e6146c295880bfcabd836df8e7f830a Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Wed, 27 Sep 2023 19:20:38 +0200 Subject: [PATCH 2/3] Fix tests This should be okay, because in both cases, the error message basically says the same thing. --- .../ErrorMessages/TypeMismatchTests.fs | 6 +++--- .../Language/SequenceExpressionTests.fs | 4 ++-- tests/fsharp/typecheck/sigs/neg24.bsl | 10 +++++++--- tests/fsharp/typecheck/sigs/version47/neg24.bsl | 10 +++++++--- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs index 7ebec39786f..06dc7d44671 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/TypeMismatchTests.fs @@ -345,9 +345,9 @@ let f4 = |> typecheck |> shouldFail |> withDiagnostics [ - (Error 193, Line 6, Col 9, Line 6, Col 16, "Type constraint mismatch. The type \n 'string' \nis not compatible with type\n 'int' \n") - (Error 193, Line 12, Col 13, Line 12, Col 16, "Type constraint mismatch. The type \n 'string' \nis not compatible with type\n 'int' \n") + (Error 1, Line 6, Col 9, Line 6, Col 16, "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ") + (Error 1, Line 12, Col 13, Line 12, Col 16, "This expression was expected to have type\n 'int' \nbut here has type\n 'string' ") (Error 193, Line 21, Col 9, Line 21, Col 24, "Type constraint mismatch. The type \n 'int list' \nis not compatible with type\n 'string seq' \n") - (Error 193, Line 28, Col 9, Line 28, Col 12, "Type constraint mismatch. The type \n 'float' \nis not compatible with type\n 'int64' \n") + (Error 1, Line 28, Col 9, Line 28, Col 12, "This expression was expected to have type\n 'int64' \nbut here has type\n 'float' ") ] diff --git a/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs index 4ad6a5cafe2..2f90f8963c6 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/SequenceExpressionTests.fs @@ -414,8 +414,8 @@ let typedSeq = |> withLangVersion80 |> typecheck |> shouldFail - |> withErrorCode 193 - |> withDiagnosticMessageMatches "Type constraint mismatch" + |> withErrorCode 1 + |> withDiagnosticMessageMatches "This expression was expected to have type" [] diff --git a/tests/fsharp/typecheck/sigs/neg24.bsl b/tests/fsharp/typecheck/sigs/neg24.bsl index 94167197aa1..f2e3feb2d54 100644 --- a/tests/fsharp/typecheck/sigs/neg24.bsl +++ b/tests/fsharp/typecheck/sigs/neg24.bsl @@ -21,11 +21,15 @@ neg24.fs(302,33,302,34): typecheck error FS0001: All elements of a list must be neg24.fs(302,36,302,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element has type 'int'. -neg24.fs(305,24,305,25): typecheck error FS0193: Type constraint mismatch. The type - 'int' -is not compatible with type +neg24.fs(305,24,305,25): typecheck error FS0001: This expression was expected to have type 'unit' +but here has type + 'int' +neg24.fs(305,31,305,32): typecheck error FS0001: This expression was expected to have type + 'unit' +but here has type + 'int' neg24.fs(308,30,308,31): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. diff --git a/tests/fsharp/typecheck/sigs/version47/neg24.bsl b/tests/fsharp/typecheck/sigs/version47/neg24.bsl index 4825319243d..192de09f93d 100644 --- a/tests/fsharp/typecheck/sigs/version47/neg24.bsl +++ b/tests/fsharp/typecheck/sigs/version47/neg24.bsl @@ -21,11 +21,15 @@ neg24.fs(302,33,302,34): typecheck error FS0001: All elements of a list must be neg24.fs(302,36,302,37): typecheck error FS0001: All elements of a list must be implicitly convertible to the type of the first element, which here is 'unit'. This element has type 'int'. -neg24.fs(305,24,305,25): typecheck error FS0193: Type constraint mismatch. The type - 'int' -is not compatible with type +neg24.fs(305,24,305,25): typecheck error FS0001: This expression was expected to have type 'unit' +but here has type + 'int' +neg24.fs(305,31,305,32): typecheck error FS0001: This expression was expected to have type + 'unit' +but here has type + 'int' neg24.fs(308,30,308,31): typecheck error FS0020: The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'. From 45af1b22fcac617339c2b00f265e8b6b8c58e10d Mon Sep 17 00:00:00 2001 From: Adam Boniecki Date: Wed, 4 Oct 2023 16:26:22 +0200 Subject: [PATCH 3/3] Add a unit test --- .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../TypeChecks/SeqTypeCheckTests.fs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/TypeChecks/SeqTypeCheckTests.fs diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 111ba0c94e5..aefeb44cc50 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -226,6 +226,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/SeqTypeCheckTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/SeqTypeCheckTests.fs new file mode 100644 index 00000000000..a0b78d83d1c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/SeqTypeCheckTests.fs @@ -0,0 +1,17 @@ +module TypeChecks.SeqTypeCheckTests + +open Xunit +open FSharp.Test.Compiler + +[] +let ``Seq expr with impicit yield type checks correctly when two identical record types are present`` () = + FSharp """ +module SeqInference + +type A = { X: int } +type B = { X: int } + +let l: A list = [ if true then { X = 42 } ] +""" + |> typecheck + |> shouldSucceed \ No newline at end of file