From fa5b9cafcf0df040008626e27d7ba58a1fdbebef Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 4 Mar 2024 19:36:46 +0000 Subject: [PATCH] Update union-case declaration AttributeTargets.Property --- src/Compiler/Checking/CheckDeclarations.fs | 25 +++++++++++++------ .../AttributeTargetsIsProperty.fs | 10 ++++++++ .../AttributeUsage/AttributeUsage.fs | 15 +++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsProperty.fs diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index c82a5edf6f3..457a3489576 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -511,14 +511,6 @@ module TcRecdUnionAndEnumDeclarations = 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 = - // The attributes of a union case decl get attached to the generated "static factory" method - // Enforce that the union-cases can only be targeted by attributes with AttributeTargets.Method - if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations) then - TcAttributes cenv env AttributeTargets.Method synAttrs - else - TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs - let vis, _ = ComputeAccessAndCompPath g env None m vis None parent let vis = CombineReprAccess parent vis @@ -571,6 +563,23 @@ module TcRecdUnionAndEnumDeclarations = let checkXmlDocs = cenv.diagnosticOptions.CheckXmlDocs let xmlDoc = xmldoc.ToXmlDoc(checkXmlDocs, Some names) + let attrs = + (* + The attributes of a union case decl get attached to the generated "static factory" method. + Enforce union-cases AttributeTargets: + - AttributeTargets.Method + type SomeUnion = + | Case1 of int // Compiles down to a static method + - AttributeTargets.Property + type SomeUnion = + | Case1 // Compiles down to a static property + *) + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsUnionCaseDeclarations) then + let target = if rfields.IsEmpty then AttributeTargets.Property else AttributeTargets.Method + TcAttributes cenv env target synAttrs + else + TcAttributes cenv env AttributeTargets.UnionCaseDecl synAttrs + Construct.NewUnionCase id rfields recordTy attrs xmlDoc vis let TcUnionCaseDecls (cenv: cenv) env (parent: ParentRef) (thisTy: TType) (thisTyInst: TypeInst) hasRQAAttribute tpenv unionCases = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsProperty.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsProperty.fs new file mode 100644 index 00000000000..42c94f1e474 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsProperty.fs @@ -0,0 +1,10 @@ + +open System + +[] +type PropertyLevelAttribute() = + inherit Attribute() + +type U = + | [] A + | [] B diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs index 5d930ea1e14..0bdc9306cb7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -71,6 +71,21 @@ module CustomAttributes_AttributeUsage = |> withLangVersionPreview |> verifyCompileAndRun |> shouldSucceed + + // SOURCE=AttributeTargetsIsProperty.fs # AttributeTargetsIsProperty.fs + [] + let ``AttributeTargetsIsProperty_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=AttributeTargetsIsProperty.fs # AttributeTargetsIsProperty.fs + [] + let ``AttributeTargetsIsProperty_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldSucceed // SOURCE=ConditionalAttribute.fs # ConditionalAttribute.fs []