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
15 changes: 11 additions & 4 deletions src/Compiler/Checking/CheckPatterns.fs
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ and ApplyUnionCaseOrExn m (cenv: cenv) env overallTy item =
UnifyTypes cenv env m overallTy g.exn_ty
CheckTyconAccessible cenv.amap m ad ecref |> ignore
let mkf mArgs args = TPat_exnconstr(ecref, args, unionRanges m mArgs)
mkf, recdFieldTysOfExnDefRef ecref, [ for f in (recdFieldsOfExnDefRef ecref) -> f.Id ]
mkf, recdFieldTysOfExnDefRef ecref, [ for f in (recdFieldsOfExnDefRef ecref) -> f ]

| Item.UnionCase(ucinfo, showDeprecated) ->
if showDeprecated then
Expand All @@ -582,7 +582,7 @@ and ApplyUnionCaseOrExn m (cenv: cenv) env overallTy item =
let inst = mkTyparInst ucref.TyconRef.TyparsNoRange ucinfo.TypeInst
UnifyTypes cenv env m overallTy resTy
let mkf mArgs args = TPat_unioncase(ucref, ucinfo.TypeInst, args, unionRanges m mArgs)
mkf, actualTysOfUnionCaseFields inst ucref, [ for f in ucref.AllFieldsAsList -> f.Id ]
mkf, actualTysOfUnionCaseFields inst ucref, [ for f in ucref.AllFieldsAsList -> f]

| _ ->
invalidArg "item" "not a union case or exception reference"
Expand Down Expand Up @@ -610,7 +610,7 @@ and TcPatLongIdentUnionCaseOrExnCase warnOnUpper cenv env ad vFlags patEnv ty (m
let extraPatterns = List ()

for id, _, pat in pairs do
match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.idText) with
match argNames |> List.tryFindIndex (fun id2 -> id.idText = id2.Id.idText) with
| None ->
extraPatterns.Add pat
match item with
Expand Down Expand Up @@ -678,7 +678,14 @@ and TcPatLongIdentUnionCaseOrExnCase warnOnUpper cenv env ad vFlags patEnv ty (m
elif numArgs < numArgTys then
if numArgTys > 1 then
// Expects tuple without enough args
errorR (Error (FSComp.SR.tcUnionCaseExpectsTupledArguments numArgTys, m))
let printTy = NicePrint.minimalStringOfType env.DisplayEnv
let missingArgs =
argNames.[numArgs..numArgTys - 1]
|> List.map (fun id -> (if id.rfield_name_generated then "" else id.DisplayName + ": ") + printTy id.FormalType)
|> String.concat (Environment.NewLine + "\t")
|> fun s -> Environment.NewLine + "\t" + s

errorR (Error (FSComp.SR.tcUnionCaseExpectsTupledArguments(numArgTys, numArgs, missingArgs), m))
else
errorR (UnionCaseWrongArguments (env.DisplayEnv, numArgTys, numArgs, m))
args @ (List.init (numArgTys - numArgs) (fun _ -> SynPat.Wild (m.MakeSynthetic()))), extraPatterns
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ tcCouldNotFindIDisposable,"Couldn't find Dispose on IDisposable, or it was overl
724,tcInvalidIndexIntoActivePatternArray,"Internal error. Invalid index into active pattern array"
725,tcUnionCaseDoesNotTakeArguments,"This union case does not take arguments"
726,tcUnionCaseRequiresOneArgument,"This union case takes one argument"
727,tcUnionCaseExpectsTupledArguments,"This union case expects %d arguments in tupled form"
727,tcUnionCaseExpectsTupledArguments,"This union case expects %d arguments in tupled form, but was given %d. The missing field arguments may be any of:%s"
728,tcFieldIsNotStatic,"Field '%s' is not static"
729,tcFieldNotLiteralCannotBeUsedInPattern,"This field is not a literal and cannot be used in a pattern"
730,tcRequireVarConstRecogOrLiteral,"This is not a variable, constant, active recognizer or literal"
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/TypedTree/TypedTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4156,7 +4156,7 @@ type TType =
(match anonInfo.TupInfo with
| TupInfo.Const false -> ""
| TupInfo.Const true -> "struct ")
+ "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + ")" + "|}"
+ "{|" + String.concat "," (Seq.map2 (fun nm ty -> nm + " " + string ty + ";") anonInfo.SortedNames tinst) + "|}"
| TType_fun (domainTy, retTy, _) -> "(" + string domainTy + " -> " + string retTy + ")"
| TType_ucase (uc, tinst) -> "ucase " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">")
| TType_var (tp, _) ->
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Tento případ typu union očekává argumenty v počtu {0} v podobě řazené kolekce členů.</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Dieser Union-Fall erwartet {0} Argumente als Tupel.</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Este caso de unión espera {0} argumentos en forma de tupla.</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Ce cas d'union attend {0} arguments basés sur des tuples</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Questo case di unione prevede {0} argomenti sotto forma di tupla</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">この共用体ケースにはタプル形式の引数を {0} 個指定してください</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">이 공용 구조체 케이스에는 튜플된 형식의 인수 {0}개가 필요합니다.</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Ten przypadek unii oczekuje {0} argumentów w postaci spójnej kolekcji</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Este caso união espera argumentos {0} na forma de tupla</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Для данного случая объединения требуется {0} аргументов в форме кортежа</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">Bu birleşim durumu grup olarak tanımlanmış biçimde {0} bağımsız değişken bekliyor</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">此联合用例需要 {0} 个元组格式的参数</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3793,8 +3793,8 @@
<note />
</trans-unit>
<trans-unit id="tcUnionCaseExpectsTupledArguments">
<source>This union case expects {0} arguments in tupled form</source>
<target state="translated">這個聯集需要 {0} 個 Tuple 形式的引數</target>
<source>This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</source>
<target state="new">This union case expects {0} arguments in tupled form, but was given {1}. The missing field arguments may be any of:{2}</target>
<note />
</trans-unit>
<trans-unit id="tcFieldIsNotStatic">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module FSharp.Compiler.ComponentTests.ErrorMessages.UnionCasePatternMatchingErrors

open Xunit
open FSharp.Test.Compiler

[<Fact>]
let ``Union matching error - Incomplete union fields`` () =
FSharp """
module Tests
type U =
| B of f1:int list * {|X:string|} * f3:U * f4: (int * System.String)

let x : U = failwith ""
let myVal =
match x with
| B -> 42"""
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Error 727, Line 9, Col 7, Line 9, Col 8,
"This union case expects 4 arguments in tupled form, but was given 0. The missing field arguments may be any of:
\tf1: int list
\t{| X: string |}
\tf3: U
\tf4: (int * System.String)")

[<Fact>]
let ``Union matching error - Named args - Name used twice`` () =
FSharp """
module Tests
type U =
| B of field: int * int
let x : U = failwith ""
let myVal =
match x with
| B (field = x; field = z) -> let y = x + z + 1 in ()"""
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Error 3175, Line 8, Col 21, Line 8, Col 26, "Union case/exception field 'field' cannot be used more than once.")

[<Fact>]
let ``Union matching error - Multiple tupled args`` () =
FSharp """
module Tests
type U =
| B of field: int * int

let x : U = failwith ""
let myVal =
match x with
| B x z -> let y = x + z + 1 in ()"""
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Error 727, Line 9, Col 7, Line 9, Col 12, "This union case expects 2 arguments in tupled form, but was given 0. The missing field arguments may be any of:
\tfield: int
\tint")

[<Fact>]
let ``Union matching error - Missing field`` () =
FSharp """
module Tests
type U =
| A
| B of int * int * int

let myVal =
match A with
| A -> 15
| B (x, _) -> 16"""
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Error 727, Line 10, Col 7, Line 10, Col 15, "This union case expects 3 arguments in tupled form, but was given 2. The missing field arguments may be any of:
\tint")
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
<Compile Include="ErrorMessages\FS0988AtEndOfFile.fs" />
<Compile Include="ErrorMessages\Repro1548.fs" />
<Compile Include="ErrorMessages\WarnIfDiscardedInList.fs" />
<Compile Include="ErrorMessages\UnionCasePatternMatchingErrors.fs"/>
<Compile Include="Language\IndexerSetterParamArray.fs" />
<Compile Include="Language\RegressionTests.fs" />
<Compile Include="Language\AttributeCheckingTests.fs" />
Expand Down
62 changes: 0 additions & 62 deletions tests/service/PatternMatchCompilationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -81,26 +81,6 @@ match 1, 2 with
]


[<Test>]
#if !NETCOREAPP
[<Ignore("These tests weren't running on desktop and this test fails")>]
#endif
let ``Union case 01 - Missing field`` () =
let _, checkResults = getParseAndCheckResults """
type U =
| A
| B of int * int * int

match A with
| B (x, _) -> let y = x + 1 in ()
"""
assertHasSymbolUsages ["x"; "y"] checkResults
dumpDiagnostics checkResults |> shouldEqual [
"(7,2--7,10): This union case expects 3 arguments in tupled form"
"(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
]


[<Test>]
#if !NETCOREAPP
[<Ignore("These tests weren't running on desktop and this test fails")>]
Expand Down Expand Up @@ -197,47 +177,6 @@ match A with
"(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
]


[<Test>]
#if !NETCOREAPP
[<Ignore("These tests weren't running on desktop and this test fails")>]
#endif
let ``Union case 07 - Named args - Name used twice`` () =
let _, checkResults = getParseAndCheckResults """
type U =
| A
| B of field: int * int

match A with
| B (field = x; field = z) -> let y = x + z + 1 in ()
"""
assertHasSymbolUsages ["x"; "y"; "z"] checkResults
dumpDiagnostics checkResults |> shouldEqual [
"(7,16--7,21): Union case/exception field 'field' cannot be used more than once."
"(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
]


[<Test>]
#if !NETCOREAPP
[<Ignore("These tests weren't running on desktop and this test fails")>]
#endif
let ``Union case 08 - Multiple tupled args`` () =
let _, checkResults = getParseAndCheckResults """
type U =
| A
| B of field: int * int

match A with
| B x z -> let y = x + z + 1 in ()
"""
assertHasSymbolUsages ["x"; "y"; "z"] checkResults
dumpDiagnostics checkResults |> shouldEqual [
"(7,2--7,7): This union case expects 2 arguments in tupled form"
"(6,6--6,7): Incomplete pattern matches on this expression. For example, the value 'A' may indicate a case not covered by the pattern(s)."
]


[<Test>]
let ``Union case 09 - Single arg`` () =
let _, checkResults = getParseAndCheckResults """
Expand All @@ -249,7 +188,6 @@ match None with
dumpDiagnostics checkResults |> shouldEqual [
]


[<Test>]
#if !NETCOREAPP
[<Ignore("These tests weren't running on desktop and this test fails")>]
Expand Down