diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index c4c2798a2df..94d57f23b01 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -3164,8 +3164,16 @@ 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.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)) // Notify the Language Service about field names in record/class declaration let ad = envinner.AccessRights @@ -3257,10 +3265,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.LogicalName ] - if fieldNames |> List.distinct |> List.length <> fieldNames.Length then - errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m)) + multiCaseUnionStructCheck unionCases writeFakeUnionCtorsToSink unionCases let repr = Construct.MakeUnionRepr unionCases diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index f79a7068cf6..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 names." +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 9ecac5b6c31..9f7ced75df2 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 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 4f7c728edf8..a799aa69d56 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 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 e57459c4a2b..fa31fba0a06 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 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 b93761c594a..d65a883e5de 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 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 1801e06c6f6..b82be281d65 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 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 b3d3c99155b..5971343763f 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 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 cfa2326e06a..a05cd1d2c67 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 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 b530606c2b9..b39c389dede 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 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 f7379662f5a..63d09e66795 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 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 f0d9472c167..f10abb60269 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 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 4cbfd16f9fa..a76a6b2a4ba 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 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 499dbad9df2..388f1d2aedd 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 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 aba607cb582..756c76f9ec2 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 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 new file mode 100644 index 00000000000..3d06c3704ae --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/UnionTypes/MultiCaseUnionStructTypes.fs @@ -0,0 +1,631 @@ +namespace FSharp.Compiler.ComponentTests.Conformance + +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 + | 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 2`` () = + 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 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'.") + ] + + + [] + 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 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'.") + ] + + [] + 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 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'.") + ] + + [] + 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 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 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'.") + ] + + [] + 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 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'.") + ] + + [] + 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 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'.") + ] + + [] + 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 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'.") + ] + + [] + 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 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'.") + ] + + [] + 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 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'.") + ] + + [] + 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 +[] +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 34`` () = + Fsx """ +namespace Foo +[] +type StructUnion = A of int | B of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (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'.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 35`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: 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 36`` () = + 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 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'.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 37`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int * string + | B of string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (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'.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 38`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * a: string + | B of string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (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'.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 39`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int * a1: string + | B of string + | C of string + """ + |> compile + |> shouldFail + |> withDiagnostics [ + (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'.") + ] + + [] + let ``If a union type has more than one case and is a struct, field must be given unique name 40`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of a: int * a1: string + | 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 41`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * string + | B of 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 42`` () = + Fsx """ +namespace Foo +[] +type StructUnion = + | A of int * string + | 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 43`` () = + 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 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'.") + ] + + [] + 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 int * string + | B of b1: string * b: string + | C of c: string * c1: string * c3: int + """ + |> 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`` () = + 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") + ] diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 9312c28403c..29cca6690d0 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -94,6 +94,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs index 885bb0aa0a2..a884ed51229 100644 --- a/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/CheckDeclarationsTests.fs @@ -80,7 +80,6 @@ namespace FSharpTest """ |> compile |> shouldSucceed - |> ignore [] let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Non-Struct DU Tree Cyclic Tree`` () = 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