Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC FS 1126 Allow lower-case DU cases when RequireQualifiedAccess is specified #13432

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ let ImplicitlyOpenOwnNamespace tcSink g amap scopem enclosingNamespacePath (env:

exception NotUpperCaseConstructor of range: range

exception NotUpperCaseConstructorWithoutRQA of range: range

let CheckNamespaceModuleOrTypeName (g: TcGlobals) (id: Ident) =
// type names '[]' etc. are used in fslib
if not g.compilingFSharpCore && id.idText.IndexOfAny IllegalCharactersInTypeAndNamespaceNames <> -1 then
Expand Down Expand Up @@ -453,16 +455,21 @@ module TcRecdUnionAndEnumDeclarations =
// Bind other elements of type definitions (constructors etc.)
//-------------------------------------------------------------------------

let CheckUnionCaseName (cenv: cenv) (id: Ident) =
let CheckUnionCaseName (cenv: cenv) (id: Ident) hasRQAAttribute =
let g = cenv.g
let name = id.idText
if name = "Tags" then
errorR(Error(FSComp.SR.tcUnionCaseNameConflictsWithGeneratedType(name, "Tags"), id.idRange))

CheckNamespaceModuleOrTypeName g id

if not (String.isLeadingIdentifierCharacterUpperCase name) && name <> opNameCons && name <> opNameNil then
errorR(NotUpperCaseConstructor(id.idRange))
if g.langVersion.SupportsFeature(LanguageFeature.LowercaseDUWhenRequireQualifiedAccess) then

if not (String.isLeadingIdentifierCharacterUpperCase name) && not hasRQAAttribute && name <> opNameCons && name <> opNameNil then
edgarfgp marked this conversation as resolved.
Show resolved Hide resolved
errorR(NotUpperCaseConstructorWithoutRQA(id.idRange))
else
if not (String.isLeadingIdentifierCharacterUpperCase name) && name <> opNameCons && name <> opNameNil then
errorR(NotUpperCaseConstructor(id.idRange))

let ValidateFieldNames (synFields: SynField list, tastFields: RecdField list) =
let seen = Dictionary()
Expand All @@ -479,13 +486,13 @@ module TcRecdUnionAndEnumDeclarations =
| _ ->
seen.Add(f.LogicalName, sf))

let TcUnionCaseDecl (cenv: cenv) env parent thisTy thisTyInst tpenv (SynUnionCase(Attributes synAttrs, SynIdent(id, _), args, xmldoc, vis, m, _)) =
let TcUnionCaseDecl (cenv: cenv) env parent thisTy thisTyInst tpenv hasRQAAttribute (SynUnionCase(Attributes synAttrs, SynIdent(id, _), args, xmldoc, vis, m, _)) =
let g = cenv.g
let attrs = TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs // the attributes of a union case decl get attached to the generated "static factory" method
let vis, _ = ComputeAccessAndCompPath env None m vis None parent
let vis = CombineReprAccess parent vis

CheckUnionCaseName cenv id
CheckUnionCaseName cenv id hasRQAAttribute

let rfields, recordTy =
match args with
Expand Down Expand Up @@ -526,8 +533,8 @@ module TcRecdUnionAndEnumDeclarations =
let xmlDoc = xmldoc.ToXmlDoc(true, Some names)
Construct.NewUnionCase id rfields recordTy attrs xmlDoc vis

let TcUnionCaseDecls cenv env parent (thisTy: TType) thisTyInst tpenv unionCases =
let unionCasesR = unionCases |> List.map (TcUnionCaseDecl cenv env parent thisTy thisTyInst tpenv)
let TcUnionCaseDecls (cenv: cenv) env (parent: ParentRef) (thisTy: TType) (thisTyInst: TypeInst) hasRQAAttribute tpenv unionCases =
let unionCasesR = unionCases |> List.map (TcUnionCaseDecl cenv env parent thisTy thisTyInst tpenv hasRQAAttribute)
unionCasesR |> CheckDuplicates (fun uc -> uc.Id) "union case"

let TcEnumDecl cenv env parent thisTy fieldTy (SynEnumCase(attributes=Attributes synAttrs; ident= SynIdent(id,_); value=v; xmlDoc=xmldoc; range=m)) =
Expand Down Expand Up @@ -3188,7 +3195,9 @@ module EstablishTypeDefinitionCores =

structLayoutAttributeCheck false
noAllowNullLiteralAttributeCheck()
TcRecdUnionAndEnumDeclarations.CheckUnionCaseName cenv unionCaseName

let hasRQAAttribute = HasFSharpAttribute cenv.g cenv.g.attrib_RequireQualifiedAccessAttribute tycon.Attribs
TcRecdUnionAndEnumDeclarations.CheckUnionCaseName cenv unionCaseName hasRQAAttribute
let unionCase = Construct.NewUnionCase unionCaseName [] thisTy [] XmlDoc.Empty tycon.Accessibility
writeFakeUnionCtorsToSink [ unionCase ]
Construct.MakeUnionRepr [ unionCase ], None, NoSafeInitInfo
Expand Down Expand Up @@ -3219,8 +3228,9 @@ module EstablishTypeDefinitionCores =
noAbstractClassAttributeCheck()
noAllowNullLiteralAttributeCheck()
structLayoutAttributeCheck false
let unionCases = TcRecdUnionAndEnumDeclarations.TcUnionCaseDecls cenv envinner innerParent thisTy thisTyInst tpenv unionCases


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
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Checking/CheckDeclarations.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,5 @@ val CheckOneSigFile:
Cancellable<TcEnv * ModuleOrNamespaceType * bool>

exception NotUpperCaseConstructor of range: range

exception NotUpperCaseConstructorWithoutRQA of range: range
5 changes: 5 additions & 0 deletions src/Compiler/Driver/CompilerDiagnostics.fs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ let GetRangeOfDiagnostic (diagnostic: PhasedDiagnostic) =
| LetRecCheckedAtRuntime m
| UpperCaseIdentifierInPattern m
| NotUpperCaseConstructor m
| NotUpperCaseConstructorWithoutRQA m
| RecursiveUseCheckedAtRuntime (_, _, m)
| LetRecEvaluatedOutOfOrder (_, _, _, m)
| DiagnosticWithText (_, _, m)
Expand Down Expand Up @@ -270,6 +271,7 @@ let GetDiagnosticNumber (diagnostic: PhasedDiagnostic) =
| UseOfAddressOfOperator _ -> 51
| DefensiveCopyWarning _ -> 52
| NotUpperCaseConstructor _ -> 53
| NotUpperCaseConstructorWithoutRQA _ -> 53
| TypeIsImplicitlyAbstract _ -> 54
// 55 cannot be reused
| DeprecatedThreadStaticBindingWarning _ -> 56
Expand Down Expand Up @@ -435,6 +437,7 @@ let ErrorFromApplyingDefault2E () = Message("ErrorFromApplyingDefault2", "")
let ErrorsFromAddingSubsumptionConstraintE () = Message("ErrorsFromAddingSubsumptionConstraint", "%s%s%s")
let UpperCaseIdentifierInPatternE () = Message("UpperCaseIdentifierInPattern", "")
let NotUpperCaseConstructorE () = Message("NotUpperCaseConstructor", "")
let NotUpperCaseConstructorWithoutRQAE () = Message("NotUpperCaseConstructorWithoutRQA", "")
let FunctionExpectedE () = Message("FunctionExpected", "")
let BakedInMemberConstraintNameE () = Message("BakedInMemberConstraintName", "%s")
let BadEventTransformationE () = Message("BadEventTransformation", "")
Expand Down Expand Up @@ -771,6 +774,8 @@ let OutputPhasedErrorR (os: StringBuilder) (diagnostic: PhasedDiagnostic) (canSu

| NotUpperCaseConstructor _ -> os.AppendString(NotUpperCaseConstructorE().Format)

| NotUpperCaseConstructorWithoutRQA _ -> os.AppendString(NotUpperCaseConstructorWithoutRQAE().Format)

| ErrorFromAddingConstraint (_, e, _) -> OutputExceptionR os e

#if !NO_TYPEPROVIDERS
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1556,6 +1556,7 @@ featureStructActivePattern,"struct representation for active patterns"
featureRelaxWhitespace2,"whitespace relaxation v2"
featureReallyLongList,"list literals of any size"
featureErrorOnDeprecatedRequireQualifiedAccess,"give error on deprecated access of construct with RequireQualifiedAccess attribute"
featureLowercaseDUWhenRequireQualifiedAccess,"Allow lowercase DU when RequireQualifiedAccess attribute"
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."
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/FSStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1107,4 +1107,7 @@
<data name="TargetInvocationExceptionWrapper" xml:space="preserve">
<value>internal error: {0}</value>
</data>
<data name="NotUpperCaseConstructorWithoutRQA" xml:space="preserve">
<value>Lowercase discriminated union cases are only allowed when using RequireQualifiedAccess attribute</value>
</data>
</root>
3 changes: 3 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type LanguageFeature =
| DelegateTypeNameResolutionFix
| ReallyLongLists
| ErrorOnDeprecatedRequireQualifiedAccess
| LowercaseDUWhenRequireQualifiedAccess

/// LanguageVersion management
type LanguageVersion(versionText) =
Expand Down Expand Up @@ -111,6 +112,7 @@ type LanguageVersion(versionText) =
LanguageFeature.BetterExceptionPrinting, previewVersion
LanguageFeature.ReallyLongLists, previewVersion
LanguageFeature.ErrorOnDeprecatedRequireQualifiedAccess, previewVersion
LanguageFeature.LowercaseDUWhenRequireQualifiedAccess, previewVersion
]

static let defaultLanguageVersion = LanguageVersion("default")
Expand Down Expand Up @@ -210,6 +212,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.DelegateTypeNameResolutionFix -> FSComp.SR.featureDelegateTypeNameResolutionFix ()
| LanguageFeature.ReallyLongLists -> FSComp.SR.featureReallyLongList ()
| LanguageFeature.ErrorOnDeprecatedRequireQualifiedAccess -> FSComp.SR.featureErrorOnDeprecatedRequireQualifiedAccess ()
| LanguageFeature.LowercaseDUWhenRequireQualifiedAccess -> FSComp.SR.featureLowercaseDUWhenRequireQualifiedAccess ()

/// Get a version string associated with the given feature.
member _.GetFeatureVersionString feature =
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type LanguageFeature =
| DelegateTypeNameResolutionFix
| ReallyLongLists
| ErrorOnDeprecatedRequireQualifiedAccess
| LowercaseDUWhenRequireQualifiedAccess

/// LanguageVersion management
type LanguageVersion =
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">rozhraní s vícenásobným obecným vytvářením instancí</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">Revize kompatibility ML</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">Schnittstellen mit mehrfacher generischer Instanziierung</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">ML-Kompatibilitätsrevisionen</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">interfaces con creación de instancias genéricas múltiples</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">Revisiones de compatibilidad de ML</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">interfaces avec plusieurs instanciations génériques</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">Réviseurs de compatibilité ML</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">interfacce con più creazioni di istanze generiche</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">Revisioni della compatibilità di Ml</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">複数のジェネリックのインスタンス化を含むインターフェイス</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">ML 互換性のリビジョン</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">여러 제네릭 인스턴스화가 포함된 인터페이스</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">ML 호환성 개정</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">interfejsy z wieloma ogólnymi wystąpieniami</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">Poprawki dotyczące zgodności Machine Learning</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">interfaces com várias instanciações genéricas</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">Revisões de compatibilidade de ML</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">интерфейсы с множественным универсальным созданием экземпляра</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">Редакции совместимости ML</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">birden çok genel örnek oluşturma içeren arabirimler</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">ML uyumluluk düzeltmeleri</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">具有多个泛型实例化的接口</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">ML 兼容性修订</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@
<target state="translated">具有多個泛型具現化的介面</target>
<note />
</trans-unit>
<trans-unit id="featureLowercaseDUWhenRequireQualifiedAccess">
<source>Allow lowercase DU when RequireQualifiedAccess attribute</source>
<target state="new">Allow lowercase DU when RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="featureMLCompatRevisions">
<source>ML compatibility revisions</source>
<target state="translated">ML 相容性修訂</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSStrings.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
<target state="translated">Nejméně jedna informační zpráva v načteném souboru\n</target>
<note />
</trans-unit>
<trans-unit id="NotUpperCaseConstructorWithoutRQA">
<source>Lowercase discriminated union cases are only allowed when using RequireQualifiedAccess attribute</source>
<target state="new">Lowercase discriminated union cases are only allowed when using RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="Parser.TOKEN.DOT.DOT.HAT">
<source>symbol '..^'</source>
<target state="translated">symbol ..^</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSStrings.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
<target state="translated">Mindestens eine Informationsmeldung in der geladenen Datei.\n</target>
<note />
</trans-unit>
<trans-unit id="NotUpperCaseConstructorWithoutRQA">
<source>Lowercase discriminated union cases are only allowed when using RequireQualifiedAccess attribute</source>
<target state="new">Lowercase discriminated union cases are only allowed when using RequireQualifiedAccess attribute</target>
<note />
</trans-unit>
<trans-unit id="Parser.TOKEN.DOT.DOT.HAT">
<source>symbol '..^'</source>
<target state="translated">Symbol "..^"</target>
Expand Down
Loading