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 []