From 894a1f80bf0a645fc5e583085c4e3167f7d5cf7a Mon Sep 17 00:00:00 2001 From: dawe Date: Tue, 23 May 2023 23:04:15 +0200 Subject: [PATCH 1/5] Add warning when compiler selects among multiple record type candidates --- src/Compiler/Checking/NameResolution.fs | 27 +++ src/Compiler/FSComp.txt | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 + src/Compiler/xlf/FSComp.txt.de.xlf | 5 + src/Compiler/xlf/FSComp.txt.es.xlf | 5 + src/Compiler/xlf/FSComp.txt.fr.xlf | 5 + src/Compiler/xlf/FSComp.txt.it.xlf | 5 + src/Compiler/xlf/FSComp.txt.ja.xlf | 5 + src/Compiler/xlf/FSComp.txt.ko.xlf | 5 + src/Compiler/xlf/FSComp.txt.pl.xlf | 5 + src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 + src/Compiler/xlf/FSComp.txt.ru.xlf | 5 + src/Compiler/xlf/FSComp.txt.tr.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 + .../ErrorMessages/NameResolutionTests.fs | 192 ++++++++++++++++++ 16 files changed, 285 insertions(+) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 6fa70c26fc7..ba61bb737f2 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2725,6 +2725,33 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf let errorTextF s = match tryTcrefOfAppTy g ty with | ValueSome tcref -> + if tcref.IsRecordTycon then + let alternative = nenv.eFieldLabels |> Map.tryFind nm + match alternative with + | Some fieldLabels -> + let fieldsOfResolvedType = tcref.AllFieldsArray |> Array.map (fun f -> f.LogicalName) |> Set.ofArray + let fieldsOfAlternatives = + fieldLabels + |> Seq.collect (fun l -> l.Tycon.AllFieldsArray |> Array.map (fun f -> f.LogicalName)) + |> Set.ofSeq + let intersect = Set.intersect fieldsOfAlternatives fieldsOfResolvedType + + if not intersect.IsEmpty then + let resolvedTypeName = $"""{System.String.Join(".", tcref.CompilationPath.DemangledPath)}.{tcref.LogicalName}""" + let namesOfAlternatives = + fieldLabels + |> List.map (fun l -> $""" %s{System.String.Join(".", l.Tycon.CompilationPath.DemangledPath)}.{l.Tycon.LogicalName}""") + |> fun names -> $""" {resolvedTypeName}""" :: names + let candidates = System.String.Join("\n", namesOfAlternatives) + let overlappingNames = + intersect + |> Set.toArray + |> Array.sort + |> Array.map (fun s -> $" {s}") + |> fun a -> System.String.Join("\n", a) + warning(Error(FSComp.SR.tcMultipleRecdTypeChoice(candidates, resolvedTypeName, overlappingNames), m)) + () + | _ -> () FSComp.SR.undefinedNameFieldConstructorOrMemberWhenTypeIsKnown(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars, s) | _ -> FSComp.SR.undefinedNameFieldConstructorOrMember(s) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 0da140f884d..a2bfa1fc156 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1692,3 +1692,4 @@ featureEscapeBracesInFormattableString,"Escapes curly braces before calling Form 3563,lexInvalidIdentifier,"This is not a valid identifier" 3564,parsMissingUnionCaseName,"Missing union case name" 3565,parsExpectingType,"Expecting type" +3566,tcMultipleRecdTypeChoice,"Multiple type matches were found:\n%s\nThe type '%s' was used. Due to the overlapping field names\n%s\nconsider using type annotations or change the order of open statements." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 68d321a7cdf..2d5a7811ad5 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1077,6 +1077,11 @@ Je třeba inicializovat následující požadované vlastnosti:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Použití metod s atributem NoEagerConstraintApplicationAttribute vyžaduje /langversion:6.0 nebo novější. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index ee52b662d1d..4d6772d83f1 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1077,6 +1077,11 @@ Die folgenden erforderlichen Eigenschaften müssen initialisiert werden:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Die Verwendung von Methoden mit "NoEagerConstraintApplicationAttribute" erfordert /langversion:6.0 oder höher. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 9748064eb19..57e0ff0bbd5 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1077,6 +1077,11 @@ Se deben inicializar las siguientes propiedades necesarias:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later El uso de métodos con "NoEagerConstraintApplicationAttribute" requiere /langversion:6.0 o posteriores diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index d0eb8a412f3..02d1e57c357 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1077,6 +1077,11 @@ Les propriétés requises suivantes doivent être initialisées :{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later L’utilisation de méthodes avec « NoEagerConstraintApplicationAttribute » requiert/langversion:6.0 ou ultérieur diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index a1c4c79cf5a..43e91cdf883 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1077,6 +1077,11 @@ È necessario inizializzare le proprietà obbligatorie seguenti:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later L'utilizzo di metodi con 'NoEagerConstraintApplicationAttribute' richiede /langversion: 6.0 o versione successiva diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index a1e4157a4de..377c7b91787 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1077,6 +1077,11 @@ 次の必須プロパティを初期化する必要があります:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 'NoEagerConstraintApplicationAttribute' を指定してメソッドを使用するには、/langversion:6.0 以降が必要です diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 7c4f481d2a2..61b052583bb 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1077,6 +1077,11 @@ 다음 필수 속성을 초기화해야 합니다. {0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 'NoEagerConstraintApplicationAttribute'와 함께 메서드를 사용하려면 /langversion:6.0 이상이 필요합니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index cea66cde2e9..73998578cc0 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1077,6 +1077,11 @@ Następujące wymagane właściwości muszą zostać zainicjowane:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Używanie metod z atrybutem "NoEagerConstraintApplicationAttribute" wymaga parametru /langversion:6.0 lub nowszego diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 79c864480fd..5b6451bea4b 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1077,6 +1077,11 @@ As seguintes propriedades necessárias precisam ser inicializadas:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Usar métodos com 'NoEagerConstraintApplicationAttribute' requer /langversion:6.0 ou posterior diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 831c7891388..912fb129ffc 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1077,6 +1077,11 @@ Необходимо инициализировать следующие обязательные свойства:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later Для использования методов с "NoEagerConstraintApplicationAttribute" требуется /langversion:6.0 или более поздняя версия diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 9e455903428..b377a94da69 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1077,6 +1077,11 @@ Aşağıdaki gerekli özelliklerin başlatılması gerekiyor:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 'NoEagerConstraintApplicationAttribute' içeren yöntemlerin kullanılması /langversion:6.0 veya üstünü gerektiriyor diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 8338b0da896..a73285cd071 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1077,6 +1077,11 @@ 必须初始化以下必需属性: {0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 将方法与 “NoEagerConstraintApplicationAttribute” 配合使用需要 /langversion:6.0 或更高版本 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 5fbdf0f332c..e20f66fde4f 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1077,6 +1077,11 @@ 下列必要的屬性必須初始化:{0} + + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + Multiple type matches were found:\n{0}\nThe type '{1}' was used. Due to the overlapping field names\n{2}\nconsider using type annotations or change the order of open statements. + + Using methods with 'NoEagerConstraintApplicationAttribute' requires /langversion:6.0 or later 使用具有 'NoEagerConstraintApplicationAttribute' 的方法需要 /langversion:6.0 或更新版本 diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs index 1862e6befe5..1b18538ba67 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs @@ -44,3 +44,195 @@ let r = { Size=3; Height=4; Wall=1 } (Error 39, Line 9, Col 29, Line 9, Col 33, "The record label 'Wall' is not defined. Maybe you want one of the following:" + System.Environment.NewLine + " Walls" + System.Environment.NewLine + " Wallis") (Error 764, Line 9, Col 9, Line 9, Col 37, "No assignment given for field 'Wallis' of type 'Test.F'") ] + + [] + let MultipleRecdTypeChoiceWarningWith1Alternative () = + FSharp """ +namespace N + +module Module1 = + + type OtherThing = + { Name: string } + +module Module2 = + + type Person = + { Name: string + City: string } + +module Lib = + + open Module2 + open Module1 + + let F thing = + let x = thing.Name + thing.City +""" + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 3566, Line 22, Col 9, Line 22, Col 19, "Multiple type matches were found:\n N.Module1.OtherThing\n N.Module2.Person\nThe type 'N.Module1.OtherThing' was used. Due to the overlapping field names\n Name\nconsider using type annotations or change the order of open statements.") + (Error 39, Line 22, Col 15, Line 22, Col 19, "The type 'OtherThing' does not define the field, constructor or member 'City'.") + ] + + [] + let MultipleRecdTypeChoiceWarningWith2Alternative () = + FSharp """ +namespace N + +module Module1 = + + type OtherThing = + { Name: string + Planet: string } + +module Module2 = + + type Person = + { Name: string + City: string + Planet: string } + +module Module3 = + + type Cafe = + { Name: string + City: string + Country: string + Planet: string } + +module Lib = + + open Module3 + open Module2 + open Module1 + + let F thing = + let x = thing.Name + thing.City +""" + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Warning 3566, Line 33, Col 9, Line 33, Col 19, "Multiple type matches were found:\n N.Module1.OtherThing\n N.Module2.Person\n N.Module3.Cafe\nThe type 'N.Module1.OtherThing' was used. Due to the overlapping field names\n Name\n Planet\nconsider using type annotations or change the order of open statements.") + (Error 39, Line 33, Col 15, Line 33, Col 19, "The type 'OtherThing' does not define the field, constructor or member 'City'.") + ] + + [] + let MultipleRecdTypeChoiceWarningNotRaisedWithCorrectOpenStmtsOrdering () = + FSharp """ +namespace N + +module Module1 = + + type OtherThing = + { Name: string + Planet: string } + +module Module2 = + + type Person = + { Name: string + City: string + Planet: string } + +module Module3 = + + type Cafe = + { Name: string + City: string + Country: string + Planet: string } + +module Lib = + + open Module3 + open Module1 + open Module2 + + let F thing = + let x = thing.Name + thing.City +""" + |> typecheck + |> shouldSucceed + + [] + let MultipleRecdTypeChoiceWarningNotRaisedWithoutOverlaps () = + FSharp """ +namespace N + +module Module1 = + + type OtherThing = + { NameX: string + Planet: string } + +module Module2 = + + type Person = + { Name: string + City: string + Planet: string } + +module Module3 = + + type Cafe = + { NameX: string + City: string + Country: string + Planet: string } + +module Lib = + + open Module3 + open Module2 + open Module1 + + let F thing = + let x = thing.Name + thing.City +""" + |> typecheck + |> shouldSucceed + + [] + let MultipleRecdTypeChoiceWarningNotRaisedWithTypeAnnotations () = + FSharp """ +namespace N + +module Module1 = + + type OtherThing = + { NameX: string + Planet: string } + +module Module2 = + + type Person = + { Name: string + City: string + Planet: string } + +module Module3 = + + type Cafe = + { NameX: string + City: string + Country: string + Planet: string } + +module Lib = + + open Module3 + open Module2 + open Module1 + + let F (thing: Person) = + let x = thing.Name + thing.City +""" + |> typecheck + |> shouldSucceed From 9bf521ecbd9205a126ec252498c57daa6750a7bc Mon Sep 17 00:00:00 2001 From: dawe Date: Wed, 24 May 2023 12:26:30 +0200 Subject: [PATCH 2/5] Use when guard instead of if --- src/Compiler/Checking/NameResolution.fs | 55 +++++++++++++------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index ba61bb737f2..8ab039976fe 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2724,34 +2724,35 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf let errorTextF s = match tryTcrefOfAppTy g ty with - | ValueSome tcref -> - if tcref.IsRecordTycon then - let alternative = nenv.eFieldLabels |> Map.tryFind nm - match alternative with - | Some fieldLabels -> - let fieldsOfResolvedType = tcref.AllFieldsArray |> Array.map (fun f -> f.LogicalName) |> Set.ofArray - let fieldsOfAlternatives = + | ValueSome tcref when tcref.IsRecordTycon -> + let alternative = nenv.eFieldLabels |> Map.tryFind nm + match alternative with + | Some fieldLabels -> + let fieldsOfResolvedType = tcref.AllFieldsArray |> Array.map (fun f -> f.LogicalName) |> Set.ofArray + let fieldsOfAlternatives = + fieldLabels + |> Seq.collect (fun l -> l.Tycon.AllFieldsArray |> Array.map (fun f -> f.LogicalName)) + |> Set.ofSeq + let intersect = Set.intersect fieldsOfAlternatives fieldsOfResolvedType + + if not intersect.IsEmpty then + let resolvedTypeName = $"""{System.String.Join(".", tcref.CompilationPath.DemangledPath)}.{tcref.LogicalName}""" + let namesOfAlternatives = fieldLabels - |> Seq.collect (fun l -> l.Tycon.AllFieldsArray |> Array.map (fun f -> f.LogicalName)) - |> Set.ofSeq - let intersect = Set.intersect fieldsOfAlternatives fieldsOfResolvedType - - if not intersect.IsEmpty then - let resolvedTypeName = $"""{System.String.Join(".", tcref.CompilationPath.DemangledPath)}.{tcref.LogicalName}""" - let namesOfAlternatives = - fieldLabels - |> List.map (fun l -> $""" %s{System.String.Join(".", l.Tycon.CompilationPath.DemangledPath)}.{l.Tycon.LogicalName}""") - |> fun names -> $""" {resolvedTypeName}""" :: names - let candidates = System.String.Join("\n", namesOfAlternatives) - let overlappingNames = - intersect - |> Set.toArray - |> Array.sort - |> Array.map (fun s -> $" {s}") - |> fun a -> System.String.Join("\n", a) - warning(Error(FSComp.SR.tcMultipleRecdTypeChoice(candidates, resolvedTypeName, overlappingNames), m)) - () - | _ -> () + |> List.map (fun l -> $""" %s{System.String.Join(".", l.Tycon.CompilationPath.DemangledPath)}.{l.Tycon.LogicalName}""") + |> fun names -> $""" {resolvedTypeName}""" :: names + let candidates = System.String.Join("\n", namesOfAlternatives) + let overlappingNames = + intersect + |> Set.toArray + |> Array.sort + |> Array.map (fun s -> $" {s}") + |> fun a -> System.String.Join("\n", a) + warning(Error(FSComp.SR.tcMultipleRecdTypeChoice(candidates, resolvedTypeName, overlappingNames), m)) + () + | _ -> () + FSComp.SR.undefinedNameFieldConstructorOrMemberWhenTypeIsKnown(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars, s) + | ValueSome tcref -> FSComp.SR.undefinedNameFieldConstructorOrMemberWhenTypeIsKnown(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars, s) | _ -> FSComp.SR.undefinedNameFieldConstructorOrMember(s) From d32ce7adafd04eabec6d0cd8b8a7feadcc914c49 Mon Sep 17 00:00:00 2001 From: dawe Date: Wed, 24 May 2023 13:07:23 +0200 Subject: [PATCH 3/5] Move string construction to NicePrint --- src/Compiler/Checking/NameResolution.fs | 8 ++++---- src/Compiler/Checking/NicePrint.fs | 2 ++ src/Compiler/Checking/NicePrint.fsi | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 8ab039976fe..4e005c2353b 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2736,17 +2736,17 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf let intersect = Set.intersect fieldsOfAlternatives fieldsOfResolvedType if not intersect.IsEmpty then - let resolvedTypeName = $"""{System.String.Join(".", tcref.CompilationPath.DemangledPath)}.{tcref.LogicalName}""" + let resolvedTypeName = NicePrint.fqnOfEntityRef tcref let namesOfAlternatives = fieldLabels - |> List.map (fun l -> $""" %s{System.String.Join(".", l.Tycon.CompilationPath.DemangledPath)}.{l.Tycon.LogicalName}""") - |> fun names -> $""" {resolvedTypeName}""" :: names + |> List.map (fun l -> $" %s{NicePrint.fqnOfEntityRef l.TyconRef}") + |> fun names -> $" %s{resolvedTypeName}" :: names let candidates = System.String.Join("\n", namesOfAlternatives) let overlappingNames = intersect |> Set.toArray |> Array.sort - |> Array.map (fun s -> $" {s}") + |> Array.map (fun s -> $" %s{s}") |> fun a -> System.String.Join("\n", a) warning(Error(FSComp.SR.tcMultipleRecdTypeChoice(candidates, resolvedTypeName, overlappingNames), m)) () diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index 2ab993e369a..df78375e022 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -2615,6 +2615,8 @@ let stringOfFSAttrib denv x = x |> PrintTypes.layoutAttrib denv |> squareAngleL let stringOfILAttrib denv x = x |> PrintTypes.layoutILAttrib denv |> squareAngleL |> showL +let fqnOfEntityRef (tcref: EntityRef) = $"""{String.Join(".", tcref.CompilationPath.DemangledPath)}.{tcref.LogicalName}""" + let layoutImpliedSignatureOfModuleOrNamespace showHeader denv infoReader ad m contents = InferredSigPrinting.layoutImpliedSignatureOfModuleOrNamespace showHeader denv infoReader ad m contents diff --git a/src/Compiler/Checking/NicePrint.fsi b/src/Compiler/Checking/NicePrint.fsi index 792ec2b44ed..95a0ede1faf 100644 --- a/src/Compiler/Checking/NicePrint.fsi +++ b/src/Compiler/Checking/NicePrint.fsi @@ -135,6 +135,8 @@ val stringOfFSAttrib: denv: DisplayEnv -> x: Attrib -> string val stringOfILAttrib: denv: DisplayEnv -> ILType * ILAttribElem list -> string +val fqnOfEntityRef: EntityRef -> string + val layoutImpliedSignatureOfModuleOrNamespace: showHeader: bool -> denv: DisplayEnv -> From 588c5aef23ed13ee066fceb8bfb63975e227f330 Mon Sep 17 00:00:00 2001 From: dawe Date: Wed, 24 May 2023 15:40:37 +0200 Subject: [PATCH 4/5] reuse layoutTyconRefImpl --- src/Compiler/Checking/NameResolution.fs | 4 ++-- src/Compiler/Checking/NicePrint.fs | 2 +- src/Compiler/Checking/NicePrint.fsi | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 4e005c2353b..2582631db35 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2736,10 +2736,10 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf let intersect = Set.intersect fieldsOfAlternatives fieldsOfResolvedType if not intersect.IsEmpty then - let resolvedTypeName = NicePrint.fqnOfEntityRef tcref + let resolvedTypeName = NicePrint.fqnOfEntityRef g tcref let namesOfAlternatives = fieldLabels - |> List.map (fun l -> $" %s{NicePrint.fqnOfEntityRef l.TyconRef}") + |> List.map (fun l -> $" %s{NicePrint.fqnOfEntityRef g l.TyconRef}") |> fun names -> $" %s{resolvedTypeName}" :: names let candidates = System.String.Join("\n", namesOfAlternatives) let overlappingNames = diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index df78375e022..95da6fa9bfd 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -2615,7 +2615,7 @@ let stringOfFSAttrib denv x = x |> PrintTypes.layoutAttrib denv |> squareAngleL let stringOfILAttrib denv x = x |> PrintTypes.layoutILAttrib denv |> squareAngleL |> showL -let fqnOfEntityRef (tcref: EntityRef) = $"""{String.Join(".", tcref.CompilationPath.DemangledPath)}.{tcref.LogicalName}""" +let fqnOfEntityRef g x = x |> layoutTyconRefImpl false (DisplayEnv.Empty g) |> showL let layoutImpliedSignatureOfModuleOrNamespace showHeader denv infoReader ad m contents = InferredSigPrinting.layoutImpliedSignatureOfModuleOrNamespace showHeader denv infoReader ad m contents diff --git a/src/Compiler/Checking/NicePrint.fsi b/src/Compiler/Checking/NicePrint.fsi index 95a0ede1faf..ffe6aa7ea84 100644 --- a/src/Compiler/Checking/NicePrint.fsi +++ b/src/Compiler/Checking/NicePrint.fsi @@ -135,7 +135,7 @@ val stringOfFSAttrib: denv: DisplayEnv -> x: Attrib -> string val stringOfILAttrib: denv: DisplayEnv -> ILType * ILAttribElem list -> string -val fqnOfEntityRef: EntityRef -> string +val fqnOfEntityRef: g: TcGlobals -> x: EntityRef -> string val layoutImpliedSignatureOfModuleOrNamespace: showHeader: bool -> From d37ffe78e4e01d8b8fe9372b5312275257719b0a Mon Sep 17 00:00:00 2001 From: dawe Date: Thu, 25 May 2023 14:12:45 +0200 Subject: [PATCH 5/5] warning when langversion preview, information otherwise --- src/Compiler/Checking/NameResolution.fs | 6 +- src/Compiler/FSComp.txt | 1 + src/Compiler/Facilities/LanguageFeatures.fs | 3 + src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 + src/Compiler/xlf/FSComp.txt.de.xlf | 5 + src/Compiler/xlf/FSComp.txt.es.xlf | 5 + src/Compiler/xlf/FSComp.txt.fr.xlf | 5 + src/Compiler/xlf/FSComp.txt.it.xlf | 5 + src/Compiler/xlf/FSComp.txt.ja.xlf | 5 + src/Compiler/xlf/FSComp.txt.ko.xlf | 5 + src/Compiler/xlf/FSComp.txt.pl.xlf | 5 + src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 + src/Compiler/xlf/FSComp.txt.ru.xlf | 5 + src/Compiler/xlf/FSComp.txt.tr.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 + .../ErrorMessages/NameResolutionTests.fs | 182 ++++++++++++------ 18 files changed, 194 insertions(+), 64 deletions(-) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 2582631db35..06672b38112 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -2748,8 +2748,10 @@ let rec ResolveLongIdentInTypePrim (ncenv: NameResolver) nenv lookupKind (resInf |> Array.sort |> Array.map (fun s -> $" %s{s}") |> fun a -> System.String.Join("\n", a) - warning(Error(FSComp.SR.tcMultipleRecdTypeChoice(candidates, resolvedTypeName, overlappingNames), m)) - () + if g.langVersion.SupportsFeature(LanguageFeature.WarningWhenMultipleRecdTypeChoice) then + warning(Error(FSComp.SR.tcMultipleRecdTypeChoice(candidates, resolvedTypeName, overlappingNames), m)) + else + informationalWarning(Error(FSComp.SR.tcMultipleRecdTypeChoice(candidates, resolvedTypeName, overlappingNames), m)) | _ -> () FSComp.SR.undefinedNameFieldConstructorOrMemberWhenTypeIsKnown(tcref.DisplayNameWithStaticParametersAndUnderscoreTypars, s) | ValueSome tcref -> diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index a2bfa1fc156..cd463878354 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1572,6 +1572,7 @@ featureStaticMembersInInterfaces,"Static members in interfaces" featureNonInlineLiteralsAsPrintfFormat,"String values marked as literals and IL constants as printf format" featureNestedCopyAndUpdate,"Nested record field copy-and-update" featureExtendedStringInterpolation,"Extended string interpolation similar to C# raw string literals." +featureWarningWhenMultipleRecdTypeChoice,"Raises warnings when multiple record type matches were found during name resolution because of overlapping field names." 3353,fsiInvalidDirective,"Invalid directive '#%s %s'" 3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." 3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index f46b0dbeee1..996b63760e8 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -67,6 +67,7 @@ type LanguageFeature = | NonInlineLiteralsAsPrintfFormat | NestedCopyAndUpdate | ExtendedStringInterpolation + | WarningWhenMultipleRecdTypeChoice /// LanguageVersion management type LanguageVersion(versionText) = @@ -157,6 +158,7 @@ type LanguageVersion(versionText) = LanguageFeature.NonInlineLiteralsAsPrintfFormat, previewVersion LanguageFeature.NestedCopyAndUpdate, previewVersion LanguageFeature.ExtendedStringInterpolation, previewVersion + LanguageFeature.WarningWhenMultipleRecdTypeChoice, previewVersion ] @@ -279,6 +281,7 @@ type LanguageVersion(versionText) = | LanguageFeature.NonInlineLiteralsAsPrintfFormat -> FSComp.SR.featureNonInlineLiteralsAsPrintfFormat () | LanguageFeature.NestedCopyAndUpdate -> FSComp.SR.featureNestedCopyAndUpdate () | LanguageFeature.ExtendedStringInterpolation -> FSComp.SR.featureExtendedStringInterpolation () + | LanguageFeature.WarningWhenMultipleRecdTypeChoice -> FSComp.SR.featureWarningWhenMultipleRecdTypeChoice () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index d12c77fdcbe..ab85fdc4aae 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -57,6 +57,7 @@ type LanguageFeature = | NonInlineLiteralsAsPrintfFormat | NestedCopyAndUpdate | ExtendedStringInterpolation + | WarningWhenMultipleRecdTypeChoice /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 2d5a7811ad5..aa360080748 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -422,6 +422,11 @@ Vyvolá upozornění, když se použije „let inline ... =“ společně s atributem [<MethodImpl(MethodImplOptions.NoInlining)>]. Funkce není vkládána. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop zástupný znak ve smyčce for diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 4d6772d83f1..315e66de94c 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -422,6 +422,11 @@ Löst Warnungen aus, wenn „let inline ... =“ zusammen mit dem Attribut [<MethodImpl(MethodImplOptions.NoInlining)>] verwendet wird. Die Funktion wird nicht inline gesetzt. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop Platzhalter in for-Schleife diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 57e0ff0bbd5..7a4c7d92114 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -422,6 +422,11 @@ Genera advertencias cuando se usa "let inline ... =" junto con el atributo [<MethodImpl(MethodImplOptions.NoInlining)>]. La función no se está insertando. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop carácter comodín en bucle for diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 02d1e57c357..567f5d14823 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -422,6 +422,11 @@ Génère des avertissements lorsque « let inline ... = » est utilisé avec l’attribut [<MethodImpl(MethodImplOptions.NoInlining)>]. La fonction n’est pas inlined. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop caractère générique dans une boucle for diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 43e91cdf883..ced44453f26 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -422,6 +422,11 @@ Genera avvisi quando 'let inline ... =' viene usato insieme all'attributo [<MethodImpl(MethodImplOptions.NoInlining)>]. La funzione non viene resa inline. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop carattere jolly nel ciclo for diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 377c7b91787..80ead6d67ec 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -422,6 +422,11 @@ 'let inline ... =' が [<MethodImpl(MethodImplOptions.NoInlining)>] 属性と一緒に使用されるときに警告を生成します。関数はインライン化されていません。 + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop for ループのワイルド カード diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 61b052583bb..5e4e1d3e174 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -422,6 +422,11 @@ 'let inline ... ='을(를) [<MethodImpl(MethodImplOptions.NoInlining)>] 특성과 함께 사용하는 경우 경고를 발생합니다. 함수가 인라인되지 않습니다. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop for 루프의 와일드카드 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 73998578cc0..83c7577b966 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -422,6 +422,11 @@ Zgłasza ostrzeżenia, gdy element „let inline ... =” jest używany razem z atrybutem [<MethodImpl(MethodImplOptions.NoInlining)>]. Funkcja nie jest wstawiana. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop symbol wieloznaczny w pętli for diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 5b6451bea4b..1ba929165ef 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -422,6 +422,11 @@ Gera avisos quando 'let inline ... =' é usado junto com o atributo [<MethodImpl(MethodImplOptions.NoInlining)>]. A função não está sendo embutida. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop curinga para loop diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 912fb129ffc..b8f4edbcc19 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -422,6 +422,11 @@ Выдает предупреждения, когда используется параметр "let inline ... =" вместе с атрибутом [<MethodImpl(MethodImplOptions.NoInlining)>]. Функция не встраивается. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop подстановочный знак в цикле for diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index b377a94da69..9e52d015bd1 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -422,6 +422,11 @@ [<MethodImpl(MethodImplOptions.NoInlining)>] özniteliği ile birlikte 'let inline ... =' kullanıldığında uyarı verir. İşlev satır içine alınmıyor. + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop for döngüsünde joker karakter diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index a73285cd071..e334d9ee3f4 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -422,6 +422,11 @@ 当 "let inline ... =" 与 [<MethodImpl(MethodImplOptions.NoInlining)>] 属性一起使用时引发警告。函数未内联。 + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop for 循环中的通配符 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index e20f66fde4f..0ff7f95e672 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -422,6 +422,11 @@ 當 'let inline ... =' 與 [<MethodImpl(MethodImplOptions.NoInlining)>] 屬性一起使用時引發警告。函數未內嵌。 + + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + Raises warnings when multiple record type matches were found during name resolution because of overlapping field names. + + wild card in for loop for 迴圈中的萬用字元 diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs index 1b18538ba67..82143e50547 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/NameResolutionTests.fs @@ -45,9 +45,7 @@ let r = { Size=3; Height=4; Wall=1 } (Error 764, Line 9, Col 9, Line 9, Col 37, "No assignment given for field 'Wallis' of type 'Test.F'") ] - [] - let MultipleRecdTypeChoiceWarningWith1Alternative () = - FSharp """ + let multipleRecdTypeChoiceWarningWith1AlternativeSource = """ namespace N module Module1 = @@ -70,6 +68,11 @@ module Lib = let x = thing.Name thing.City """ + + [] + let MultipleRecdTypeChoiceWarningWith1AlternativeLangPreview () = + FSharp multipleRecdTypeChoiceWarningWith1AlternativeSource + |> withLangVersionPreview |> typecheck |> shouldFail |> withDiagnostics [ @@ -78,8 +81,17 @@ module Lib = ] [] - let MultipleRecdTypeChoiceWarningWith2Alternative () = - FSharp """ + let MultipleRecdTypeChoiceWarningWith1AlternativeLang7 () = + FSharp multipleRecdTypeChoiceWarningWith1AlternativeSource + |> withLangVersion70 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Information 3566, Line 22, Col 9, Line 22, Col 19, "Multiple type matches were found:\n N.Module1.OtherThing\n N.Module2.Person\nThe type 'N.Module1.OtherThing' was used. Due to the overlapping field names\n Name\nconsider using type annotations or change the order of open statements.") + (Error 39, Line 22, Col 15, Line 22, Col 19, "The type 'OtherThing' does not define the field, constructor or member 'City'.") + ] + + let multipleRecdTypeChoiceWarningWith2AlternativeSource = """ namespace N module Module1 = @@ -113,6 +125,11 @@ module Lib = let x = thing.Name thing.City """ + + [] + let MultipleRecdTypeChoiceWarningWith2AlternativeLangPreview () = + FSharp multipleRecdTypeChoiceWarningWith2AlternativeSource + |> withLangVersionPreview |> typecheck |> shouldFail |> withDiagnostics [ @@ -121,47 +138,66 @@ module Lib = ] [] - let MultipleRecdTypeChoiceWarningNotRaisedWithCorrectOpenStmtsOrdering () = - FSharp """ + let MultipleRecdTypeChoiceWarningWith2AlternativeLang7 () = + FSharp multipleRecdTypeChoiceWarningWith2AlternativeSource + |> withLangVersion70 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Information 3566, Line 33, Col 9, Line 33, Col 19, "Multiple type matches were found:\n N.Module1.OtherThing\n N.Module2.Person\n N.Module3.Cafe\nThe type 'N.Module1.OtherThing' was used. Due to the overlapping field names\n Name\n Planet\nconsider using type annotations or change the order of open statements.") + (Error 39, Line 33, Col 15, Line 33, Col 19, "The type 'OtherThing' does not define the field, constructor or member 'City'.") + ] + + let multipleRecdTypeChoiceWarningNotRaisedWithCorrectOpenStmtsOrderingSource = """ namespace N module Module1 = - type OtherThing = - { Name: string - Planet: string } + type OtherThing = + { Name: string + Planet: string } module Module2 = - type Person = - { Name: string - City: string - Planet: string } + type Person = + { Name: string + City: string + Planet: string } module Module3 = - type Cafe = - { Name: string - City: string - Country: string - Planet: string } + type Cafe = + { Name: string + City: string + Country: string + Planet: string } module Lib = - open Module3 - open Module1 - open Module2 + open Module3 + open Module1 + open Module2 - let F thing = - let x = thing.Name - thing.City + let F thing = + let x = thing.Name + thing.City """ + + [] + let MultipleRecdTypeChoiceWarningNotRaisedWithCorrectOpenStmtsOrderingLangPreview () = + FSharp multipleRecdTypeChoiceWarningNotRaisedWithCorrectOpenStmtsOrderingSource + |> withLangVersionPreview |> typecheck |> shouldSucceed [] - let MultipleRecdTypeChoiceWarningNotRaisedWithoutOverlaps () = - FSharp """ + let MultipleRecdTypeChoiceWarningNotRaisedWithCorrectOpenStmtsOrderingLang7 () = + FSharp multipleRecdTypeChoiceWarningNotRaisedWithCorrectOpenStmtsOrderingSource + |> withLangVersion70 + |> typecheck + |> shouldSucceed + + let multipleRecdTypeChoiceWarningNotRaisedWithoutOverlapsSource = """ namespace N module Module1 = @@ -195,44 +231,66 @@ module Lib = let x = thing.Name thing.City """ + + [] + let MultipleRecdTypeChoiceWarningNotRaisedWithoutOverlapsLangPreview () = + FSharp multipleRecdTypeChoiceWarningNotRaisedWithoutOverlapsSource + |> withLangVersionPreview |> typecheck |> shouldSucceed - + [] - let MultipleRecdTypeChoiceWarningNotRaisedWithTypeAnnotations () = - FSharp """ -namespace N - -module Module1 = - - type OtherThing = - { NameX: string - Planet: string } - -module Module2 = - - type Person = - { Name: string - City: string - Planet: string } - -module Module3 = - - type Cafe = - { NameX: string - City: string - Country: string - Planet: string } - -module Lib = - - open Module3 - open Module2 - open Module1 + let MultipleRecdTypeChoiceWarningNotRaisedWithoutOverlapsLang7 () = + FSharp multipleRecdTypeChoiceWarningNotRaisedWithoutOverlapsSource + |> withLangVersion70 + |> typecheck + |> shouldSucceed - let F (thing: Person) = - let x = thing.Name - thing.City -""" + let multipleRecdTypeChoiceWarningNotRaisedWithTypeAnnotationsSource = """ + namespace N + + module Module1 = + + type OtherThing = + { NameX: string + Planet: string } + + module Module2 = + + type Person = + { Name: string + City: string + Planet: string } + + module Module3 = + + type Cafe = + { NameX: string + City: string + Country: string + Planet: string } + + module Lib = + + open Module3 + open Module2 + open Module1 + + let F (thing: Person) = + let x = thing.Name + thing.City + """ + + [] + let MultipleRecdTypeChoiceWarningNotRaisedWithTypeAnnotationsLangPreview () = + FSharp multipleRecdTypeChoiceWarningNotRaisedWithTypeAnnotationsSource + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + + [] + let MultipleRecdTypeChoiceWarningNotRaisedWithTypeAnnotationsLang7 () = + FSharp multipleRecdTypeChoiceWarningNotRaisedWithTypeAnnotationsSource + |> withLangVersion70 |> typecheck |> shouldSucceed