Skip to content

Commit 5a19ccf

Browse files
authored
Delegates allowed to target AttributeTargets.Class AttributeTargets.Struct AttributeTargets.Interface incorrectly (#16891)
1 parent 6b7aa6e commit 5a19ccf

File tree

8 files changed

+77
-4
lines changed

8 files changed

+77
-4
lines changed

docs/release-notes/.FSharp.Compiler.Service/8.0.300.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824))
2222
* Fix broken code completion after a record type declaration ([PR #16813](https://github.com/dotnet/fsharp/pull/16813))
2323
* Enforce AttributeTargets on enums ([PR #16887](https://github.com/dotnet/fsharp/pull/16887))
24+
* Enforce AttributeTargets on delegates ([PR #16891](https://github.com/dotnet/fsharp/pull/16891))
2425

2526
### Added
2627

docs/release-notes/.FSharp.Core/8.0.300.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77

88
* Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568))
99
* Enforce AttributeTargets on structs and classes. Also update `RequireQualifiedAccessAttribute` and `AutoOpenAttribute` to use `AttributeTargets.Struct` ([PR #16790](https://github.com/dotnet/fsharp/pull/16790))
10-
* Enforce AttributeTargets on enums. Also update `RequireQualifiedAccessAttribute` to use `AttributeTargets.Enum` ([PR #16887](https://github.com/dotnet/fsharp/pull/16887))
10+
* Enforce AttributeTargets on enums. Also update `RequireQualifiedAccessAttribute` to use `AttributeTargets.Enum` ([PR #16887](https://github.com/dotnet/fsharp/pull/16887))
11+
* Enforce AttributeTargets on delegates. Also update `ReflectedDefinitionAttribute` to use `AttributeTargets.Delegate` ([PR #16891](https://github.com/dotnet/fsharp/pull/16891))

src/Compiler/Checking/CheckDeclarations.fs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2931,7 +2931,10 @@ module EstablishTypeDefinitionCores =
29312931
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
29322932
TFSharpClass
29332933
| SynTypeDefnKind.Interface -> TFSharpInterface
2934-
| SynTypeDefnKind.Delegate _ -> TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None))
2934+
| SynTypeDefnKind.Delegate _ ->
2935+
if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then
2936+
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Delegate synAttrs |> ignore
2937+
TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None))
29352938
| SynTypeDefnKind.Struct ->
29362939
if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then
29372940
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore

src/FSharp.Core/prim-types.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ namespace Microsoft.FSharp.Core
163163

164164
[<AttributeUsage (AttributeTargets.Class ||| AttributeTargets.Struct |||
165165
AttributeTargets.Parameter ||| AttributeTargets.Method |||
166-
AttributeTargets.Property ||| AttributeTargets.Constructor, AllowMultiple=false)>]
166+
AttributeTargets.Property ||| AttributeTargets.Constructor |||
167+
AttributeTargets.Delegate, AllowMultiple=false)>]
167168
[<Sealed>]
168169
type ReflectedDefinitionAttribute(includeValue: bool) =
169170
inherit Attribute()

src/FSharp.Core/prim-types.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ namespace Microsoft.FSharp.Core
129129
/// for use at runtime.</summary>
130130
///
131131
/// <category>Attributes</category>
132-
[<AttributeUsage (AttributeTargets.Class ||| AttributeTargets.Struct ||| AttributeTargets.Parameter ||| AttributeTargets.Method ||| AttributeTargets.Property ||| AttributeTargets.Constructor,AllowMultiple=false)>]
132+
[<AttributeUsage (AttributeTargets.Class ||| AttributeTargets.Struct ||| AttributeTargets.Parameter ||| AttributeTargets.Method ||| AttributeTargets.Property ||| AttributeTargets.Constructor ||| AttributeTargets.Delegate, AllowMultiple=false)>]
133133
[<Sealed>]
134134
type ReflectedDefinitionAttribute =
135135
inherit Attribute
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
open System
2+
3+
[<AttributeUsage(AttributeTargets.Delegate)>]
4+
type CustomDelegateAttribute() =
5+
inherit Attribute()
6+
7+
[<CustomDelegate>]
8+
type Delegate1 = delegate of int -> int

tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,4 +555,40 @@ module CustomAttributes_AttributeUsage =
555555
(Error 842, Line 20, Col 3, Line 20, Col 14, "This attribute is not valid for use on this language element")
556556
(Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element")
557557
(Error 842, Line 22, Col 3, Line 22, Col 17, "This attribute is not valid for use on this language element")
558+
]
559+
560+
// SOURCE=AttributeTargetsIsDelegate01.fs # AttributeTargetsIsDelegate01.fs
561+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"AttributeTargetsIsDelegate01.fs"|])>]
562+
let ``AttributeTargetsIsDelegate01_fs`` compilation =
563+
compilation
564+
|> verifyCompile
565+
|> shouldSucceed
566+
567+
// SOURCE=AttributeTargetsIsDelegate01.fs # AttributeTargetsIsDelegate01.fs
568+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"AttributeTargetsIsDelegate01.fs"|])>]
569+
let ``AttributeTargetsIsDelegate01_fs preview`` compilation =
570+
compilation
571+
|> withLangVersionPreview
572+
|> verifyCompile
573+
|> shouldSucceed
574+
575+
// SOURCE=E_AttributeTargetIsDelegate01.fs # E_AttributeTargetIsDelegate01.fs
576+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsDelegate01.fs"|])>]
577+
let ``E_AttributeTargetIsDelegate01_fs`` compilation =
578+
compilation
579+
|> verifyCompile
580+
|> shouldSucceed
581+
582+
// SOURCE=E_AttributeTargetIsDelegate01.fs # E_AttributeTargetIsDelegate01.fs
583+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsDelegate01.fs"|])>]
584+
let ``E_AttributeTargetsIsDelegate01_fs preview`` compilation =
585+
compilation
586+
|> withLangVersionPreview
587+
|> verifyCompile
588+
|> shouldFail
589+
|> withDiagnostics [
590+
(Error 842, Line 19, Col 3, Line 19, Col 14, "This attribute is not valid for use on this language element")
591+
(Error 842, Line 20, Col 3, Line 20, Col 15, "This attribute is not valid for use on this language element")
592+
(Error 842, Line 21, Col 3, Line 21, Col 18, "This attribute is not valid for use on this language element")
593+
(Error 842, Line 22, Col 3, Line 22, Col 13, "This attribute is not valid for use on this language element")
558594
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
open System
2+
3+
[<AttributeUsage(AttributeTargets.Class)>]
4+
type CustomClassAttribute() =
5+
inherit Attribute()
6+
7+
[<AttributeUsage(AttributeTargets.Struct)>]
8+
type CustomStructAttribute() =
9+
inherit Attribute()
10+
11+
[<AttributeUsage(AttributeTargets.Interface)>]
12+
type CustomInterfaceAttribute() =
13+
inherit Attribute()
14+
15+
[<AttributeUsage(AttributeTargets.Enum)>]
16+
type CustomEnumAttribute() =
17+
inherit Attribute()
18+
19+
[<CustomClass>]
20+
[<CustomStruct>]
21+
[<CustomInterface>]
22+
[<CustomEnum>]
23+
type Delegate1 = delegate of int -> int

0 commit comments

Comments
 (0)