From 475eac427cc91a144a053e92059a914ecdcf2520 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 13 Oct 2022 19:41:30 +0200 Subject: [PATCH 1/7] Improve Unclear error FS3204 multicase union case struct --- src/Compiler/Checking/CheckDeclarations.fs | 9 ++- .../UnionTypes/MultiCaseUnionStructTypes.fs | 80 +++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 3bb776b2399..37ace879539 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3256,9 +3256,12 @@ module EstablishTypeDefinitionCores = let hasRQAAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv unionCases if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then - let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft.LogicalName ] - if fieldNames |> List.distinct |> List.length <> fieldNames.Length then - errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m)) + let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft ] + let fieldNamesDis = fieldNames |> List.map(fun field -> field.LogicalName) + if fieldNamesDis |> List.distinct |> List.length <> fieldNamesDis.Length then + for field in fieldNames do + if field.rfield_name_generated then + errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), field.Range)) writeFakeUnionCtorsToSink unionCases let repr = Construct.MakeUnionRepr unionCases diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs new file mode 100644 index 00000000000..599d6e3cf17 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -0,0 +1,80 @@ +namespace FSharp.Compiler.ComponentTests.Conformance + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +module MultiCaseUnionStructTypes = + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. 1`` () = + Fsx """ +namespace Foo +[] +type A = + | B of a: int + | C of c: string + | D of string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. 2`` () = + Fsx """ +namespace Foo +[] +type A = + | B of a: int * string + | C of c: string + | D of string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. 3`` () = + Fsx """ +namespace Foo +[] +type A = + | B of a: int * x: string + | C of c: string + | D of string + """ + |> compile + |> shouldSucceed + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. 4`` () = + Fsx """ +namespace Foo +[] +type A = + | B of int + | C of string + | D of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. 5`` () = + Fsx """ +namespace Foo +[] +type A = + | B of a: int + | C of string + | D of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 75e0f8a0323..c59356898f3 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -94,6 +94,7 @@ + From 1dc8914b4ac9b212f50703f8371b5f8e344fce14 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 14 Oct 2022 06:58:11 +0200 Subject: [PATCH 2/7] More unit tests --- src/Compiler/Checking/CheckDeclarations.fs | 4 +-- .../UnionTypes/MultiCaseUnionStructTypes.fs | 36 +++++++++++++++++-- tests/fsharp/typecheck/sigs/neg95.bsl | 8 +---- tests/fsharp/typecheck/sigs/neg95.fs | 9 ----- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 37ace879539..311ea3cae4a 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3257,8 +3257,8 @@ module EstablishTypeDefinitionCores = let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv unionCases if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft ] - let fieldNamesDis = fieldNames |> List.map(fun field -> field.LogicalName) - if fieldNamesDis |> List.distinct |> List.length <> fieldNamesDis.Length then + let fieldNamesDistinct = fieldNames |> List.map(fun field -> field.LogicalName) + if fieldNamesDistinct |> List.distinct |> List.length <> fieldNamesDistinct.Length then for field in fieldNames do if field.rfield_name_generated then errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), field.Range)) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs index 599d6e3cf17..b2d914687ff 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -5,7 +5,6 @@ open FSharp.Test open FSharp.Test.Compiler module MultiCaseUnionStructTypes = - [] let ``If a union type has more than one case and is a struct, field must be given unique name. 1`` () = Fsx """ @@ -15,6 +14,9 @@ type A = | B of a: int | C of c: string | D of string + +[] +type StructUnion3 = A of X:int | B of X:string """ |> compile |> shouldSucceed @@ -44,8 +46,36 @@ type A = """ |> compile |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. involves an immediate cyclic reference 4`` () = + Fsx """ +namespace Foo +[] +type StructUnion4 = A of X:int | B of Y:StructUnion4 + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 954, Line 4, Col 6, Line 4, Col 18, "This type definition involves an immediate cyclic reference through a struct field or inheritance relation") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. 5`` () = + Fsx """ +namespace Foo +[] +type StructUnion2 = A of int | B of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 4, Col 26, Line 4, Col 29, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + (Error 3204, Line 4, Col 37, Line 4, Col 43, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + ] + [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 4`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name. 6`` () = Fsx """ namespace Foo [] @@ -63,7 +93,7 @@ type A = ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 5`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name. 7`` () = Fsx """ namespace Foo [] diff --git a/tests/fsharp/typecheck/sigs/neg95.bsl b/tests/fsharp/typecheck/sigs/neg95.bsl index 48eddb2718a..ba9ceefb4e6 100644 --- a/tests/fsharp/typecheck/sigs/neg95.bsl +++ b/tests/fsharp/typecheck/sigs/neg95.bsl @@ -13,10 +13,4 @@ neg95.fs(39,7,39,18): typecheck error FS3200: In a recursive declaration group, neg95.fs(45,10,45,22): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation -neg95.fs(52,10,52,21): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation - -neg95.fs(55,10,55,22): typecheck error FS3204: If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - -neg95.fs(58,10,58,22): typecheck error FS3204: If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - -neg95.fs(61,10,61,22): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation +neg95.fs(52,10,52,21): typecheck error FS0954: This type definition involves an immediate cyclic reference through a struct field or inheritance relation \ No newline at end of file diff --git a/tests/fsharp/typecheck/sigs/neg95.fs b/tests/fsharp/typecheck/sigs/neg95.fs index 07f26f7ef35..a8268129826 100644 --- a/tests/fsharp/typecheck/sigs/neg95.fs +++ b/tests/fsharp/typecheck/sigs/neg95.fs @@ -50,12 +50,3 @@ namespace Neg95B [] type StructUnion = StructUnion of float * StructUnion - - [] - type StructUnion2 = A of int | B of string - - [] - type StructUnion3 = A of X:int | B of X:string - - [] - type StructUnion4 = A of X:int | B of Y:StructUnion4 From 0fa8dc56cdebf452305532cbae7425bc76ff19c6 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 14 Oct 2022 13:53:53 +0200 Subject: [PATCH 3/7] UUpdate compiler error message and use the field the field range --- src/Compiler/Checking/CheckDeclarations.fs | 8 +- src/Compiler/FSComp.txt | 2 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 +- src/Compiler/xlf/FSComp.txt.de.xlf | 4 +- src/Compiler/xlf/FSComp.txt.es.xlf | 4 +- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 +- src/Compiler/xlf/FSComp.txt.it.xlf | 4 +- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 +- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 +- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 +- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 +- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 +- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 +- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 +- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 +- .../UnionTypes/MultiCaseUnionStructTypes.fs | 195 ++++++++++++++---- 16 files changed, 184 insertions(+), 73 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 311ea3cae4a..670bcb74715 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3257,11 +3257,9 @@ module EstablishTypeDefinitionCores = let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv unionCases if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft ] - let fieldNamesDistinct = fieldNames |> List.map(fun field -> field.LogicalName) - if fieldNamesDistinct |> List.distinct |> List.length <> fieldNamesDistinct.Length then - for field in fieldNames do - if field.rfield_name_generated then - errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), field.Range)) + for field in fieldNames do + if field.rfield_name_generated then + errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), field.Range)) writeFakeUnionCtorsToSink unionCases let repr = Construct.MakeUnionRepr unionCases diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index f79a7068cf6..fc136dae96d 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1372,7 +1372,7 @@ tcTupleStructMismatch,"One tuple type is a struct tuple, the other is a referenc 3201,tcModuleAbbrevFirstInMutRec,"In a recursive declaration group, module abbreviations must come after all 'open' declarations and before other declarations" 3202,tcUnsupportedMutRecDecl,"This declaration is not supported in recursive declaration groups" 3203,parsInvalidUseOfRec,"Invalid use of 'rec' keyword" -3204,tcStructUnionMultiCaseDistinctFields,"If a union type has more than one case and is a struct, then all fields within the union type must be given unique names." +3204,tcStructUnionMultiCaseDistinctFields,"If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned)." 3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute." 3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'" 3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 9ecac5b6c31..16613e99e9e 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Pokud je typ sjednocení struktura a obsahuje více než jeden případ, všem polím v tomto typu sjednocení se musí přiřadit jedinečný název. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Pokud je typ sjednocení struktura a obsahuje více než jeden případ, všem polím v tomto typu sjednocení se musí přiřadit jedinečný název. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 4f7c728edf8..dc5df9bf7ce 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Wenn ein Union-Typ mehrere case-Anweisungen aufweist und eine Struktur ist, müssen für alle Felder im Union-Typ eindeutige Namen angegeben werden. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Wenn ein Union-Typ mehrere case-Anweisungen aufweist und eine Struktur ist, müssen für alle Felder im Union-Typ eindeutige Namen angegeben werden. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index e57459c4a2b..b99e9dd1dba 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Si un tipo de unión tiene más de un caso y un struct, a todos los campos dentro del tipo de unión se les deben dar nombres únicos. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Si un tipo de unión tiene más de un caso y un struct, a todos los campos dentro del tipo de unión se les deben dar nombres únicos. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index b93761c594a..faa1d040ab2 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Si un type union a plusieurs étiquettes case, et s'il s'agit d'un struct, tous les champs du type union doivent avoir des noms uniques. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Si un type union a plusieurs étiquettes case, et s'il s'agit d'un struct, tous les champs du type union doivent avoir des noms uniques. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 1801e06c6f6..cf336805b27 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Se un tipo di unione contiene più di un case ed è una struttura, è necessario assegnare nomi univoci a tutti i campi all'interno del tipo di unione. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Se un tipo di unione contiene più di un case ed è una struttura, è necessario assegnare nomi univoci a tutti i campi all'interno del tipo di unione. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index b3d3c99155b..e14def0e0b5 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - 共用体型が複数のケースを持つ 1 つの構造体である場合は、共用体型内のすべてのフィールドに一意の名前を付ける必要があります。 + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + 共用体型が複数のケースを持つ 1 つの構造体である場合は、共用体型内のすべてのフィールドに一意の名前を付ける必要があります。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index cfa2326e06a..0fe0c0de31c 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - 공용 구조체 형식이 둘 이상의 case를 포함하고 구조체인 경우 공용 구조체 형식 내의 모든 필드에 고유한 이름을 지정해야 합니다. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + 공용 구조체 형식이 둘 이상의 case를 포함하고 구조체인 경우 공용 구조체 형식 내의 모든 필드에 고유한 이름을 지정해야 합니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index b530606c2b9..46de5ccb7ec 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Jeśli typ unii ma więcej niż jeden przypadek i jest strukturą, wszystkim polom w typie unii należy nadać unikatowe nazwy. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Jeśli typ unii ma więcej niż jeden przypadek i jest strukturą, wszystkim polom w typie unii należy nadać unikatowe nazwy. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index f7379662f5a..725d8bee22f 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Se um tipo de união tiver mais de um caso e for struct, então todos os campos dentro do tipo de união deverão ter nomes exclusivos. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Se um tipo de união tiver mais de um caso e for struct, então todos os campos dentro do tipo de união deverão ter nomes exclusivos. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index f0d9472c167..fcbb583b46e 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Если тип объединения имеет более одного варианта и является структурой, всем полям в типе объединения необходимо присвоить уникальные имена. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Если тип объединения имеет более одного варианта и является структурой, всем полям в типе объединения необходимо присвоить уникальные имена. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 4cbfd16f9fa..ccf4a47de60 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - Bir birleşim türü büyük ve küçük harfler içeriyorsa ve bir yapıysa, birleşim türü içindeki tüm alanlara benzersiz adlar verilmelidir. + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + Bir birleşim türü büyük ve küçük harfler içeriyorsa ve bir yapıysa, birleşim türü içindeki tüm alanlara benzersiz adlar verilmelidir. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 499dbad9df2..4f15a6762af 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - 如果联合类型有多个用例且为结构,则必须赋予此联合类型中的所有字段唯一的名称。 + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + 如果联合类型有多个用例且为结构,则必须赋予此联合类型中的所有字段唯一的名称。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index aba607cb582..b8753b48de9 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -7513,8 +7513,8 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - 如果等位型別有一個以上的案例並且為結構,等位型別內所有欄位的名稱就都不得重複。 + If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + 如果等位型別有一個以上的案例並且為結構,等位型別內所有欄位的名稱就都不得重複。 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs index b2d914687ff..9f318752399 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -1,110 +1,223 @@ namespace FSharp.Compiler.ComponentTests.Conformance open Xunit -open FSharp.Test open FSharp.Test.Compiler module MultiCaseUnionStructTypes = [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 1`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 1`` () = Fsx """ namespace Foo [] -type A = - | B of a: int - | C of c: string - | D of string - +type StructUnion = A of a: int | B of b:string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 2`` () = + Fsx """ +namespace Foo [] -type StructUnion3 = A of X:int | B of X:string +type StructUnion = + | A of a: int + | B of b: string """ |> compile |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 2`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 3`` () = Fsx """ namespace Foo [] -type A = - | B of a: int * string - | C of c: string - | D of string +type StructUnion = + | A of a: int * a1: string + | B of b: string """ |> compile |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 3`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 4`` () = Fsx """ namespace Foo [] -type A = - | B of a: int * x: string - | C of c: string - | D of string +type StructUnion = A of int | B of string """ |> compile - |> shouldSucceed - + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 4, Col 25, Line 4, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 4, Col 36, Line 4, Col 42, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + [] - let ``If a union type has more than one case and is a struct, field must be given unique name. involves an immediate cyclic reference 4`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 5`` () = Fsx """ namespace Foo [] -type StructUnion4 = A of X:int | B of Y:StructUnion4 +type StructUnion = + | A of a: int + | B of string """ |> compile |> shouldFail |> withDiagnostics [ - (Error 954, Line 4, Col 6, Line 4, Col 18, "This type definition involves an immediate cyclic reference through a struct field or inheritance relation") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 6`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * string + | B of string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 7`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int * string + | B of string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 5`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 8`` () = Fsx """ namespace Foo [] -type StructUnion2 = A of int | B of string +type StructUnion = + | A of int * a: string + | B of string + | C of string """ |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 4, Col 26, Line 4, Col 29, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") - (Error 3204, Line 4, Col 37, Line 4, Col 43, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] - + [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 6`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 9`` () = Fsx """ namespace Foo [] -type A = - | B of int +type StructUnion = + | A of a: int * a1: string + | B of string | C of string - | D of string """ |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name. 7`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 10`` () = Fsx """ namespace Foo [] -type A = - | B of a: int +type StructUnion = + | A of a: int * a1: string + | B of b: string | C of string - | D of string """ |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique names.") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 11`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * string + | B of string + | C of c: string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 12`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * string + | B of b: string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 13`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int * string + | B of string * b: string + | C of c: string * string * c3: int + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 24, Line 7, Col 30, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name. involves an immediate cyclic reference`` () = + Fsx """ +namespace Foo +[] +type StructUnion = A of X:int | B of Y:StructUnion + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 954, Line 4, Col 6, Line 4, Col 17, "This type definition involves an immediate cyclic reference through a struct field or inheritance relation") ] \ No newline at end of file From 77e1a72931d1116b19944a980606fb72aedf1cc7 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 14 Oct 2022 15:00:21 +0200 Subject: [PATCH 4/7] Fix failing test --- .../UnionTypes/MultiCaseUnionStructTypes.fs | 29 ++++++++++++++++++- .../TypeChecks/CheckDeclarationsTests.fs | 3 +- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs index 9f318752399..fde079efce3 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -220,4 +220,31 @@ type StructUnion = A of X:int | B of Y:StructUnion |> shouldFail |> withDiagnostics [ (Error 954, Line 4, Col 6, Line 4, Col 17, "This type definition involves an immediate cyclic reference through a struct field or inheritance relation") - ] \ No newline at end of file + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 14`` () = + Fsx """ +namespace Foo +[] +type NotATree = + | Empty + | Children of struct (int * string) + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 6, Col 19, Line 6, Col 40, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 15`` () = + Fsx """ +namespace Foo +[] +type NotATree = + | Empty + | Children of a: struct (int * string) + """ + |> compile + |> shouldSucceed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs index 885bb0aa0a2..7c69c4ec191 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs @@ -79,7 +79,8 @@ namespace FSharpTest | Children of struct (int * string) """ |> compile - |> shouldSucceed + |> shouldFail + |> withErrorCode 3204 |> ignore [] From 518ba7cb4f6d2469d19ff6c4535bc86190805948 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sat, 15 Oct 2022 14:32:59 +0200 Subject: [PATCH 5/7] Fix PR comments --- src/Compiler/Checking/CheckDeclarations.fs | 21 +- .../UnionTypes/MultiCaseUnionStructTypes.fs | 507 ++++++++++++++++-- .../TypeChecks/CheckDeclarationsTests.fs | 4 +- 3 files changed, 468 insertions(+), 64 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 5c537d1613f..410d9784312 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3162,8 +3162,21 @@ module EstablishTypeDefinitionCores = if not ctorArgNames.IsEmpty then errorR (Error(FSComp.SR.parsOnlyClassCanTakeValueArguments(), m)) let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner - let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false + let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false + + let multiCaseUnionStructCheck (unionCases: UnionCase list) = + if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then + let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft ] + let fieldNames = fieldNames |> List.map(fun x -> (x.LogicalName, x.rfield_name_generated, x.Range)) + + if fieldNames |> List.distinctBy(fun (name, _, _) -> name) |> List.length <> fieldNames.Length then + let fieldRanges = + fieldNames + |> List.filter(fun (name, isGenerated, _) -> (not isGenerated || name = "Item") || isGenerated) + |> List.map(fun (_, _, m) -> m) + for m in fieldRanges do + errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m)) // Notify the Language Service about field names in record/class declaration let ad = envinner.AccessRights @@ -3255,11 +3268,7 @@ module EstablishTypeDefinitionCores = let hasRQAAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv unionCases - if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then - let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft ] - for field in fieldNames do - if field.rfield_name_generated then - errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), field.Range)) + multiCaseUnionStructCheck unionCases writeFakeUnionCtorsToSink unionCases let repr = Construct.MakeUnionRepr unionCases diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs index fde079efce3..ce426492869 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -4,12 +4,15 @@ open Xunit open FSharp.Test.Compiler module MultiCaseUnionStructTypes = + [] let ``If a union type has more than one case and is a struct, field must be given unique name 1`` () = Fsx """ namespace Foo [] -type StructUnion = A of a: int | B of b:string +type StructUnion = + | A + | B of string """ |> compile |> shouldSucceed @@ -19,15 +22,431 @@ type StructUnion = A of a: int | B of b:string Fsx """ namespace Foo [] +type StructUnion = + | A + | B of b: string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 3`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A + | B of string + | C + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 4`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A + | B of b: string + | C + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 5`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A + | B of b: string + | C of bool + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 6`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A + | B + | C of bool + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 7`` () = + Fsx """ +namespace Foo +[] +type NotATree = + | Empty + | Children of struct (int * string) + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 8`` () = + Fsx """ +namespace Foo +[] +type NotATree = + | Empty + | Children of struct (int * string) + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 9`` () = + Fsx """ +namespace Foo +[] +type NotATree = + | Empty + | Children of a: struct (int * string) + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 10`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int + | B of string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 11`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int + | B of string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 12`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int + | B of b: string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 13`` () = + Fsx """ +namespace Foo +[] type StructUnion = | A of a: int | B of b: string + | C of string """ |> compile |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name 3`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 14`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int + | B of b: string + | C of c: string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 15`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: int + | B of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 16`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: int + | B of Item: string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 17`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: int + | B of item : string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 18`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of item: int + | B of item: string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 19`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: int * string + | B of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 24, Line 5, Col 30, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 20`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: int * item: string + | B of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 21`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: int * item: string + | B of item: string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 12, Line 6, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 22`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: int * string + | B of item: string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 23`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of item: string * int + | B of string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 24`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of item: string * item: int + | B of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3176, Line 5, Col 27, Line 5, Col 31, "Named field 'item' is used more than once.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 25`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of Item: string * Item: int + | B of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (Error 3176, Line 5, Col 27, Line 5, Col 31, "Named field 'Item' is used more than once.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 26`` () = + Fsx """ +namespace Foo +[] +type StructUnion = A of a: int | B of b:string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 27`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int + | B of b: string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 28`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int * a1: string + | B of string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 29`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * string + | B of string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 30`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int * string + | B of string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 31`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * a1: string + | B of string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 32`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int + | B of b: string + """ + |> compile + |> shouldSucceed + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 33`` () = Fsx """ namespace Foo [] @@ -39,7 +458,7 @@ type StructUnion = |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name 4`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 34`` () = Fsx """ namespace Foo [] @@ -53,7 +472,7 @@ type StructUnion = A of int | B of string ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name 5`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 35`` () = Fsx """ namespace Foo [] @@ -62,13 +481,10 @@ type StructUnion = | B of string """ |> compile - |> shouldFail - |> withDiagnostics [ - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - ] + |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name 6`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 36`` () = Fsx """ namespace Foo [] @@ -87,7 +503,7 @@ type StructUnion = ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name 7`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 37`` () = Fsx """ namespace Foo [] @@ -99,13 +515,14 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name 8`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 38`` () = Fsx """ namespace Foo [] @@ -118,12 +535,13 @@ type StructUnion = |> shouldFail |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 18, Line 5, Col 19, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name 9`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 39`` () = Fsx """ namespace Foo [] @@ -135,12 +553,14 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 21, Line 5, Col 23, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name 10`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 40`` () = Fsx """ namespace Foo [] @@ -150,13 +570,10 @@ type StructUnion = | C of string """ |> compile - |> shouldFail - |> withDiagnostics [ - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - ] + |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name 11`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 41`` () = Fsx """ namespace Foo [] @@ -166,15 +583,10 @@ type StructUnion = | C of c: string """ |> compile - |> shouldFail - |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - ] + |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name 12`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 42`` () = Fsx """ namespace Foo [] @@ -184,15 +596,10 @@ type StructUnion = | C of string """ |> compile - |> shouldFail - |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - ] + |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name 13`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 43`` () = Fsx """ namespace Foo [] @@ -204,47 +611,37 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 6, Col 21, Line 6, Col 22, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 12, Line 7, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 7, Col 24, Line 7, Col 30, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 7, Col 33, Line 7, Col 35, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] - let ``If a union type has more than one case and is a struct, field must be given unique name. involves an immediate cyclic reference`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name 44`` () = Fsx """ namespace Foo [] -type StructUnion = A of X:int | B of Y:StructUnion +type StructUnion = + | A of int * string + | B of b1: string * b: string + | C of c: string * c1: string * c3: int """ |> compile - |> shouldFail - |> withDiagnostics [ - (Error 954, Line 4, Col 6, Line 4, Col 17, "This type definition involves an immediate cyclic reference through a struct field or inheritance relation") - ] + |> shouldSucceed [] - let ``If a union type has more than one case and is a struct, field must be given unique name 14`` () = + let ``If a union type has more than one case and is a struct, field must be given unique name. involves an immediate cyclic reference`` () = Fsx """ namespace Foo [] -type NotATree = - | Empty - | Children of struct (int * string) +type StructUnion = A of X:int | B of Y:StructUnion """ |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 6, Col 19, Line 6, Col 40, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 954, Line 4, Col 6, Line 4, Col 17, "This type definition involves an immediate cyclic reference through a struct field or inheritance relation") ] - - [] - let ``If a union type has more than one case and is a struct, field must be given unique name 15`` () = - Fsx """ -namespace Foo -[] -type NotATree = - | Empty - | Children of a: struct (int * string) - """ - |> compile - |> shouldSucceed \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs index 7c69c4ec191..a884ed51229 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs @@ -79,9 +79,7 @@ namespace FSharpTest | Children of struct (int * string) """ |> compile - |> shouldFail - |> withErrorCode 3204 - |> ignore + |> shouldSucceed [] let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Non-Struct DU Tree Cyclic Tree`` () = From 46b5aebb38de2c407d0fae5142c9b9b3592851e9 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 17 Oct 2022 14:49:44 +0200 Subject: [PATCH 6/7] Remove filtering if the LogicalName is generated and update tests --- src/Compiler/Checking/CheckDeclarations.fs | 13 ++++--------- .../UnionTypes/MultiCaseUnionStructTypes.fs | 16 ---------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 44b55615e54..a86747c5fb8 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3166,15 +3166,10 @@ module EstablishTypeDefinitionCores = let multiCaseUnionStructCheck (unionCases: UnionCase list) = if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then - let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft ] - let fieldNames = fieldNames |> List.map(fun x -> (x.LogicalName, x.rfield_name_generated, x.Range)) - - if fieldNames |> List.distinctBy(fun (name, _, _) -> name) |> List.length <> fieldNames.Length then - let fieldRanges = - fieldNames - |> List.filter(fun (name, isGenerated, _) -> (not isGenerated || name = "Item") || isGenerated) - |> List.map(fun (_, _, m) -> m) - + let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield (ft.LogicalName, ft.Range) ] + let distFieldNames = fieldNames |> List.distinctBy fst + if distFieldNames.Length <> fieldNames.Length then + let fieldRanges = distFieldNames |> List.map snd for m in fieldRanges do errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m)) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs index ce426492869..f39180aa2ae 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -131,8 +131,6 @@ type StructUnion = |> shouldFail |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] @@ -151,7 +149,6 @@ type StructUnion = |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -169,7 +166,6 @@ type StructUnion = |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -211,7 +207,6 @@ type StructUnion = |> shouldFail |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -227,7 +222,6 @@ type StructUnion = |> shouldFail |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -255,7 +249,6 @@ type StructUnion = |> shouldFail |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -272,7 +265,6 @@ type StructUnion = |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 24, Line 5, Col 30, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -289,7 +281,6 @@ type StructUnion = |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -306,7 +297,6 @@ type StructUnion = |> withDiagnostics [ (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -468,7 +458,6 @@ type StructUnion = A of int | B of string |> shouldFail |> withDiagnostics [ (Error 3204, Line 4, Col 25, Line 4, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 4, Col 36, Line 4, Col 42, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -499,7 +488,6 @@ type StructUnion = (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -518,7 +506,6 @@ type StructUnion = (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -537,7 +524,6 @@ type StructUnion = (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 18, Line 5, Col 19, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -556,7 +542,6 @@ type StructUnion = (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 5, Col 21, Line 5, Col 23, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] [] @@ -616,7 +601,6 @@ type StructUnion = (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 6, Col 21, Line 6, Col 22, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 7, Col 12, Line 7, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 24, Line 7, Col 30, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") (Error 3204, Line 7, Col 33, Line 7, Col 35, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") ] From 39830d9a0b0bbbf15b5a3763a8668533564ff08f Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 17 Oct 2022 15:05:37 +0200 Subject: [PATCH 7/7] Updated error message --- src/Compiler/FSComp.txt | 2 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 2 +- src/Compiler/xlf/FSComp.txt.de.xlf | 2 +- src/Compiler/xlf/FSComp.txt.es.xlf | 2 +- src/Compiler/xlf/FSComp.txt.fr.xlf | 2 +- src/Compiler/xlf/FSComp.txt.it.xlf | 2 +- src/Compiler/xlf/FSComp.txt.ja.xlf | 2 +- src/Compiler/xlf/FSComp.txt.ko.xlf | 2 +- src/Compiler/xlf/FSComp.txt.pl.xlf | 2 +- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 2 +- src/Compiler/xlf/FSComp.txt.ru.xlf | 2 +- src/Compiler/xlf/FSComp.txt.tr.xlf | 2 +- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 2 +- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 2 +- .../UnionTypes/MultiCaseUnionStructTypes.fs | 66 +++++++++---------- 15 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index fc136dae96d..8e934660a11 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1372,7 +1372,7 @@ tcTupleStructMismatch,"One tuple type is a struct tuple, the other is a referenc 3201,tcModuleAbbrevFirstInMutRec,"In a recursive declaration group, module abbreviations must come after all 'open' declarations and before other declarations" 3202,tcUnsupportedMutRecDecl,"This declaration is not supported in recursive declaration groups" 3203,parsInvalidUseOfRec,"Invalid use of 'rec' keyword" -3204,tcStructUnionMultiCaseDistinctFields,"If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned)." +3204,tcStructUnionMultiCaseDistinctFields,"If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'." 3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute." 3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'" 3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 16613e99e9e..9f7ced75df2 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Pokud je typ sjednocení struktura a obsahuje více než jeden případ, všem polím v tomto typu sjednocení se musí přiřadit jedinečný název. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index dc5df9bf7ce..a799aa69d56 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Wenn ein Union-Typ mehrere case-Anweisungen aufweist und eine Struktur ist, müssen für alle Felder im Union-Typ eindeutige Namen angegeben werden. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index b99e9dd1dba..fa31fba0a06 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Si un tipo de unión tiene más de un caso y un struct, a todos los campos dentro del tipo de unión se les deben dar nombres únicos. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index faa1d040ab2..d65a883e5de 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Si un type union a plusieurs étiquettes case, et s'il s'agit d'un struct, tous les champs du type union doivent avoir des noms uniques. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index cf336805b27..b82be281d65 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Se un tipo di unione contiene più di un case ed è una struttura, è necessario assegnare nomi univoci a tutti i campi all'interno del tipo di unione. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index e14def0e0b5..5971343763f 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. 共用体型が複数のケースを持つ 1 つの構造体である場合は、共用体型内のすべてのフィールドに一意の名前を付ける必要があります。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 0fe0c0de31c..a05cd1d2c67 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. 공용 구조체 형식이 둘 이상의 case를 포함하고 구조체인 경우 공용 구조체 형식 내의 모든 필드에 고유한 이름을 지정해야 합니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 46de5ccb7ec..b39c389dede 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Jeśli typ unii ma więcej niż jeden przypadek i jest strukturą, wszystkim polom w typie unii należy nadać unikatowe nazwy. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 725d8bee22f..63d09e66795 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Se um tipo de união tiver mais de um caso e for struct, então todos os campos dentro do tipo de união deverão ter nomes exclusivos. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index fcbb583b46e..f10abb60269 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Если тип объединения имеет более одного варианта и является структурой, всем полям в типе объединения необходимо присвоить уникальные имена. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index ccf4a47de60..a76a6b2a4ba 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. Bir birleşim türü büyük ve küçük harfler içeriyorsa ve bir yapıysa, birleşim türü içindeki tüm alanlara benzersiz adlar verilmelidir. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 4f15a6762af..388f1d2aedd 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. 如果联合类型有多个用例且为结构,则必须赋予此联合类型中的所有字段唯一的名称。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index b8753b48de9..756c76f9ec2 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -7513,7 +7513,7 @@ - If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned). + If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'. 如果等位型別有一個以上的案例並且為結構,等位型別內所有欄位的名稱就都不得重複。 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs index f39180aa2ae..3d06c3704ae 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -130,7 +130,7 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] @@ -147,8 +147,8 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -164,8 +164,8 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 12, Line 6, Col 13, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -206,7 +206,7 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -221,7 +221,7 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -248,7 +248,7 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -263,8 +263,8 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 24, Line 5, Col 30, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 24, Line 5, Col 30, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -279,8 +279,8 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -295,8 +295,8 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 16, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 24, Line 5, Col 28, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -457,7 +457,7 @@ type StructUnion = A of int | B of string |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 4, Col 25, Line 4, Col 28, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 4, Col 25, Line 4, Col 28, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -485,9 +485,9 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 18, Line 5, Col 24, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -503,9 +503,9 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -521,9 +521,9 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 18, Line 5, Col 19, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 15, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 18, Line 5, Col 19, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -539,9 +539,9 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 21, Line 5, Col 23, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 21, Line 5, Col 23, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] [] @@ -596,12 +596,12 @@ type StructUnion = |> compile |> shouldFail |> withDiagnostics [ - (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 6, Col 21, Line 6, Col 22, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 12, Line 7, Col 13, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") - (Error 3204, Line 7, Col 33, Line 7, Col 35, "If a union type has more than one case and is a struct, then all fields within the union type must be given unique field names. For example: 'type A = B of b: int | C of c: int' (unique field names 'b' and 'c' assigned).") + (Error 3204, Line 5, Col 12, Line 5, Col 13, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 5, Col 21, Line 5, Col 27, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 12, Line 6, Col 18, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 6, Col 21, Line 6, Col 22, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 7, Col 12, Line 7, Col 13, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") + (Error 3204, Line 7, Col 33, Line 7, Col 35, "If a multicase union type is a struct, then all union cases must have unique names. For example: 'type A = B of b: int | C of c: int'.") ] []