Skip to content

Commit

Permalink
Fix inference for same (but distinct) record types in seq CE (#16040)
Browse files Browse the repository at this point in the history
* Try TcExprFlex

Seems like it could be done better, right now there are two type
checking passes for same expression

* Fix tests

This should be okay, because in both cases, the error message basically
says the same thing.

* Add a unit test
  • Loading branch information
abonie authored Oct 9, 2023
1 parent 532b57a commit 111c08b
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/Compiler/Checking/CheckComputationExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2210,14 +2210,15 @@ 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
else
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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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' ")
]

Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@
<Compile Include="Interop\StaticsInInterfaces.fs" />
<Compile Include="Interop\VisibilityTests.fs" />
<Compile Include="Scripting\Interactive.fs" />
<Compile Include="TypeChecks\SeqTypeCheckTests.fs" />
<Compile Include="TypeChecks\CheckDeclarationsTests.fs" />
<Compile Include="TypeChecks\Graph\Utils.fs" />
<Compile Include="TypeChecks\Graph\QueryTrieTests.fs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"


[<Literal>]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module TypeChecks.SeqTypeCheckTests

open Xunit
open FSharp.Test.Compiler

[<Fact>]
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
10 changes: 7 additions & 3 deletions tests/fsharp/typecheck/sigs/neg24.bsl
Original file line number Diff line number Diff line change
Expand Up @@ -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'.

Expand Down
10 changes: 7 additions & 3 deletions tests/fsharp/typecheck/sigs/version47/neg24.bsl
Original file line number Diff line number Diff line change
Expand Up @@ -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'.

Expand Down

0 comments on commit 111c08b

Please sign in to comment.