Skip to content

Commit ea04308

Browse files
authored
Improve Unclear error FS3204 Multicase union struct (#14105)
* Improve Unclear error FS3204 multicase union case struct
1 parent 1617a15 commit ea04308

20 files changed

+671
-50
lines changed

src/Compiler/Checking/CheckDeclarations.fs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3164,8 +3164,16 @@ module EstablishTypeDefinitionCores =
31643164
if not ctorArgNames.IsEmpty then errorR (Error(FSComp.SR.parsOnlyClassCanTakeValueArguments(), m))
31653165

31663166
let envinner = AddDeclaredTypars CheckForDuplicateTypars (tycon.Typars m) envinner
3167-
let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false
3168-
3167+
let envinner = MakeInnerEnvForTyconRef envinner thisTyconRef false
3168+
3169+
let multiCaseUnionStructCheck (unionCases: UnionCase list) =
3170+
if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then
3171+
let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield (ft.LogicalName, ft.Range) ]
3172+
let distFieldNames = fieldNames |> List.distinctBy fst
3173+
if distFieldNames.Length <> fieldNames.Length then
3174+
let fieldRanges = distFieldNames |> List.map snd
3175+
for m in fieldRanges do
3176+
errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m))
31693177

31703178
// Notify the Language Service about field names in record/class declaration
31713179
let ad = envinner.AccessRights
@@ -3257,10 +3265,7 @@ module EstablishTypeDefinitionCores =
32573265

32583266
let hasRQAAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs
32593267
let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst hasRQAAttribute tpenv unionCases
3260-
if tycon.IsStructRecordOrUnionTycon && unionCases.Length > 1 then
3261-
let fieldNames = [ for uc in unionCases do for ft in uc.FieldTable.TrueInstanceFieldsAsList do yield ft.LogicalName ]
3262-
if fieldNames |> List.distinct |> List.length <> fieldNames.Length then
3263-
errorR(Error(FSComp.SR.tcStructUnionMultiCaseDistinctFields(), m))
3268+
multiCaseUnionStructCheck unionCases
32643269

32653270
writeFakeUnionCtorsToSink unionCases
32663271
let repr = Construct.MakeUnionRepr unionCases

src/Compiler/FSComp.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,7 @@ tcTupleStructMismatch,"One tuple type is a struct tuple, the other is a referenc
13721372
3201,tcModuleAbbrevFirstInMutRec,"In a recursive declaration group, module abbreviations must come after all 'open' declarations and before other declarations"
13731373
3202,tcUnsupportedMutRecDecl,"This declaration is not supported in recursive declaration groups"
13741374
3203,parsInvalidUseOfRec,"Invalid use of 'rec' keyword"
1375-
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."
1375+
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'."
13761376
3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute."
13771377
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'"
13781378
3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression."

src/Compiler/xlf/FSComp.txt.cs.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">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.</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">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.</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

src/Compiler/xlf/FSComp.txt.de.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">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.</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">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.</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

src/Compiler/xlf/FSComp.txt.es.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">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.</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">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.</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

src/Compiler/xlf/FSComp.txt.fr.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">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.</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">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.</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

src/Compiler/xlf/FSComp.txt.it.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">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.</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">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.</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

src/Compiler/xlf/FSComp.txt.ja.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">共用体型が複数のケースを持つ 1 つの構造体である場合は、共用体型内のすべてのフィールドに一意の名前を付ける必要があります。</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">共用体型が複数のケースを持つ 1 つの構造体である場合は、共用体型内のすべてのフィールドに一意の名前を付ける必要があります。</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

src/Compiler/xlf/FSComp.txt.ko.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">공용 구조체 형식이 둘 이상의 case를 포함하고 구조체인 경우 공용 구조체 형식 내의 모든 필드에 고유한 이름을 지정해야 합니다.</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">공용 구조체 형식이 둘 이상의 case를 포함하고 구조체인 경우 공용 구조체 형식 내의 모든 필드에 고유한 이름을 지정해야 합니다.</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

src/Compiler/xlf/FSComp.txt.pl.xlf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7513,8 +7513,8 @@
75137513
<note />
75147514
</trans-unit>
75157515
<trans-unit id="tcStructUnionMultiCaseDistinctFields">
7516-
<source>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.</source>
7517-
<target state="translated">Jeśli typ unii ma więcej niż jeden przypadek i jest strukturą, wszystkim polom w typie unii należy nadać unikatowe nazwy.</target>
7516+
<source>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'.</source>
7517+
<target state="needs-review-translation">Jeśli typ unii ma więcej niż jeden przypadek i jest strukturą, wszystkim polom w typie unii należy nadać unikatowe nazwy.</target>
75187518
<note />
75197519
</trans-unit>
75207520
<trans-unit id="CallerMemberNameIsOverriden">

0 commit comments

Comments
 (0)