From 06d9a578b7e20e12134a9210ca69d60f51618b7b Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 29 Feb 2024 16:52:42 +0000 Subject: [PATCH 01/14] Enforce AttributeTargets.Class and AttributeTargets.Struct --- src/Compiler/Checking/CheckDeclarations.fs | 10 +++- 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 ++ .../AttributeUsage/AttributeUsage.fs | 52 +++++++++++++++++++ .../E_AttributeTargetIsClass.fs | 23 ++++++++ .../E_AttributeTargetIsMethod04.fs | 15 ++++++ .../E_AttributeTargetIsStruct.fs | 23 ++++++++ 21 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsMethod04.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index fc2e5e9d19b..534f9fd5f4b 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -2909,10 +2909,16 @@ module EstablishTypeDefinitionCores = | _ -> let kind = match kind with - | SynTypeDefnKind.Class -> TFSharpClass + | SynTypeDefnKind.Class -> + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnStructAndClasses) then + TcAttributes cenv envinner AttributeTargets.Class synAttrs |> ignore + TFSharpClass | SynTypeDefnKind.Interface -> TFSharpInterface | SynTypeDefnKind.Delegate _ -> TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None)) - | SynTypeDefnKind.Struct -> TFSharpStruct + | SynTypeDefnKind.Struct -> + if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnStructAndClasses) then + TcAttributes cenv envinner AttributeTargets.Struct synAttrs |> ignore + TFSharpStruct | _ -> error(InternalError("should have inferred tycon kind", m)) TFSharpTyconRepr (Construct.NewEmptyFSharpTyconData kind) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index a1086629fbe..b8d54c7a010 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1596,6 +1596,7 @@ featureUnionIsPropertiesVisible,"Union case test properties" featureBooleanReturningAndReturnTypeDirectedPartialActivePattern,"Boolean-returning and return-type-directed partial active patterns" featureEnforceAttributeTargetsOnFunctions,"Enforce AttributeTargets on functions" featureLowerInterpolatedStringToConcat,"Optimizes interpolated strings in certain cases, by lowering to concatenation" +featureEnforceAttributeTargetsOnStructAndClasses,"Enforce AttributeTargets on structs and classes" 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." 3355,tcNotAnIndexerNamedIndexingNotYetEnabled,"The value '%s' is not a function and does not support index notation." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 6e2d91bc6cd..5f9f932baf5 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -87,6 +87,7 @@ type LanguageFeature = | BooleanReturningAndReturnTypeDirectedPartialActivePattern | EnforceAttributeTargetsOnFunctions | LowerInterpolatedStringToConcat + | EnforceAttributeTargetsOnStructAndClasses /// LanguageVersion management type LanguageVersion(versionText) = @@ -201,6 +202,7 @@ type LanguageVersion(versionText) = LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern, previewVersion LanguageFeature.EnforceAttributeTargetsOnFunctions, previewVersion LanguageFeature.LowerInterpolatedStringToConcat, previewVersion + LanguageFeature.EnforceAttributeTargetsOnStructAndClasses, previewVersion ] static let defaultLanguageVersion = LanguageVersion("default") @@ -346,6 +348,7 @@ type LanguageVersion(versionText) = FSComp.SR.featureBooleanReturningAndReturnTypeDirectedPartialActivePattern () | LanguageFeature.EnforceAttributeTargetsOnFunctions -> FSComp.SR.featureEnforceAttributeTargetsOnFunctions () | LanguageFeature.LowerInterpolatedStringToConcat -> FSComp.SR.featureLowerInterpolatedStringToConcat () + | LanguageFeature.EnforceAttributeTargetsOnStructAndClasses -> FSComp.SR.featureEnforceAttributeTargetsOnStructAndClasses () /// 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 4888479d867..fec3a2a2c39 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -78,6 +78,7 @@ type LanguageFeature = | BooleanReturningAndReturnTypeDirectedPartialActivePattern | EnforceAttributeTargetsOnFunctions | LowerInterpolatedStringToConcat + | EnforceAttributeTargetsOnStructAndClasses /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index d4142d783fa..7d4668c3c3d 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Vyvolá chyby pro přepsání jiných než virtuálních členů diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index fa0904ef50f..872bde0f918 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Löst Fehler für Außerkraftsetzungen nicht virtueller Member aus. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 2d5ada63574..008e0be898e 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Genera errores para invalidaciones de miembros no virtuales diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index da3c6f4b9b6..4cabe084888 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Déclenche des erreurs pour les remplacements de membres non virtuels diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 010e34a81a2..c72a72a98a0 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Genera errori per gli override dei membri non virtuali diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 8a92ac2ea9e..0cea7032cb0 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides 仮想メンバー以外のオーバーライドに対してエラーを発生させます diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 51778bd4145..54bd877ead4 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides 비가상 멤버 재정의에 대한 오류 발생 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index a8a3f05ba9a..ed5274d6c2e 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Zgłasza błędy w przypadku przesłonięć elementów innych niż wirtualne diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 1f62f9a3d04..a2f1eacacbb 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Gera erros para substituições de membros não virtuais diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 64ce92b6125..56d6a3b7807 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Вызывает ошибки при переопределениях невиртуальных элементов diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index d77dfd672ec..ca8cfa02460 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides Sanal olmayan üyelerde geçersiz kılmalar için hatalar oluştur diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 5393d25202a..7fb6a93a0e7 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides 引发非虚拟成员替代的错误 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index f75fc155fde..4708c413fe4 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -297,6 +297,11 @@ Enforce AttributeTargets on functions + + Enforce AttributeTargets on structs and classes + Enforce AttributeTargets on structs and classes + + Raises errors for non-virtual members overrides 引發非虛擬成員覆寫的錯誤 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 c7861ee3e56..98b636cebe3 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -236,6 +236,18 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 52, Col 6, Line 52, Col 16, "This attribute is not valid for use on this language element") ] + // SOURCE=E_AttributeTargetIsMethod04.fs # E_AttributeTargetIsMethod04.fs + [] + let ``E_AttributeTargetIsMethod04_fs`` compilation = + compilation + |> withOptions ["--nowarn:25"] + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 10, Col 3, Line 10, Col 15, "This attribute is not valid for use on this language element") + (Error 842, Line 13, Col 3, Line 13, Col 15, "This attribute is not valid for use on this language element") + ] + // SOURCE=E_ConditionalAttribute.fs SCFLAGS="--test:ErrorRanges" # E_ConditionalAttribute.fs [] let ``E_ConditionalAttribute_fs`` compilation = @@ -278,6 +290,46 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 12, Col 3, Line 12, Col 6, "This attribute is not valid for use on this language element") ] + // SOURCE=E_AttributeTargetIsClass.fs # E_AttributeTargetIsClass.fs + [] + let ``E_AttributeTargetIsClass_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsClass.fs # E_AttributeTargetIsClass.fs + [] + let ``E_AttributeTargetIsClass_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 13, Col 3, Line 13, Col 15, "This attribute is not valid for use on this language element") + (Error 842, Line 19, Col 3, Line 19, Col 15, "This attribute is not valid for use on this language element") + (Error 842, Line 22, Col 10, Line 22, Col 22, "This attribute is not valid for use on this language element") + ] + + // SOURCE=E_AttributeTargetIsStruct.fs # E_AttributeTargetIsStruct.fs + [] + let ``E_AttributeTargetIsStruct_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsStruct.fs # E_AttributeTargetIsStruct.fs + [] + let ``E_AttributeTargetIsStruct_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 13, Col 3, Line 13, Col 14, "This attribute is not valid for use on this language element") + (Error 842, Line 19, Col 3, Line 19, Col 14, "This attribute is not valid for use on this language element") + (Error 842, Line 22, Col 11, Line 22, Col 22, "This attribute is not valid for use on this language element") + ] + // SOURCE=MarshalAsAttribute.fs # MarshalAsAttribute.fs [] let ``MarshalAsAttribute_fs`` compilation = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs new file mode 100644 index 00000000000..2f80591c13c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs @@ -0,0 +1,23 @@ +// This tests that AttributeTargets.Struct is not allowed on a class, and that AttributeTargets.Class is not allowed on a struct. + +open System + +[] +type CustomStructAttribute() = + inherit Attribute() + +[] +type CustomClassAttribute() = + inherit Attribute() + +[] +type Class(x: int) = class end + +[] +type Class2(x: int) = class end + +[] +type Class3(x: int) = class end + +[] +type Class4 = class end diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsMethod04.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsMethod04.fs new file mode 100644 index 00000000000..bd78c8fd5d5 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsMethod04.fs @@ -0,0 +1,15 @@ +// This tests that AttributeTargets.Method is not allowed in class and struct types. + +open System +open System.Diagnostics + +[] +type CustomMethodAttribute() = + inherit Attribute() + +[] +type Class() = class end + +[] +type Struct(x: int) = struct end + diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs new file mode 100644 index 00000000000..cd4e47e4e97 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs @@ -0,0 +1,23 @@ +// This tests that AttributeTargets.Class is not allowed on a struct, and that AttributeTargets.Struct is not allowed on a class. + +open System + +[] +type CustomStructAttribute() = + inherit Attribute() + +[] +type CustomClassAttribute() = + inherit Attribute() + +[] +type Struct(x: int) = struct end + +[] +type Struct1(x: int) = struct end + +[] +type Struct2(x: int) = struct end + +[] +type Struct4 = struct end \ No newline at end of file From f938cddef4d9e29f4e79d8f5cc8c6ed2524988b6 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 29 Feb 2024 20:49:48 +0000 Subject: [PATCH 02/14] Enforce AttributeTargets.Class properly in the compiler --- src/Compiler/Service/SemanticClassification.fs | 1 - src/Compiler/Service/SemanticClassification.fsi | 1 - .../CustomAttributes/AttributeUsage/AttributeUsage.fs | 1 + .../AttributeUsage/E_AttributeTargetIsClass.fs | 6 ++++++ .../AttributeUsage/E_AttributeTargetIsStruct.fs | 9 ++++++++- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Service/SemanticClassification.fs b/src/Compiler/Service/SemanticClassification.fs index 6ebbb3c8ae0..6053f996ece 100644 --- a/src/Compiler/Service/SemanticClassification.fs +++ b/src/Compiler/Service/SemanticClassification.fs @@ -58,7 +58,6 @@ type SemanticClassificationType = | TypeDef = 35 | Plaintext = 36 -[] [] type SemanticClassificationItem = val Range: range diff --git a/src/Compiler/Service/SemanticClassification.fsi b/src/Compiler/Service/SemanticClassification.fsi index ce5d6d88aeb..1fb4cf28df5 100644 --- a/src/Compiler/Service/SemanticClassification.fsi +++ b/src/Compiler/Service/SemanticClassification.fsi @@ -49,7 +49,6 @@ type SemanticClassificationType = | TypeDef = 35 | Plaintext = 36 -[] [] type SemanticClassificationItem = val Range: range 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 98b636cebe3..45d4b6789e9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -328,6 +328,7 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 13, Col 3, Line 13, Col 14, "This attribute is not valid for use on this language element") (Error 842, Line 19, Col 3, Line 19, Col 14, "This attribute is not valid for use on this language element") (Error 842, Line 22, Col 11, Line 22, Col 22, "This attribute is not valid for use on this language element") + (Error 842, Line 25, Col 3, Line 25, Col 25, "This attribute is not valid for use on this language element") ] // SOURCE=MarshalAsAttribute.fs # MarshalAsAttribute.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs index 2f80591c13c..28da51fb5ab 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs @@ -21,3 +21,9 @@ type Class3(x: int) = class end [] type Class4 = class end + +[] //RequireQualifiedAccess is marked AttributeTargets.Class +type SemanticClassificationItem = + val Range: int + val Type: string + new((range, ty)) = { Range = range; Type = ty } \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs index cd4e47e4e97..71fac8b8238 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs @@ -20,4 +20,11 @@ type Struct1(x: int) = struct end type Struct2(x: int) = struct end [] -type Struct4 = struct end \ No newline at end of file +type Struct4 = struct end + +[] //RequireQualifiedAccess is marked AttributeTargets.Class. so this should be an error +[] +type SemanticClassificationItem = + val Range: int + val Type: string + new((range, ty)) = { Range = range; Type = ty } \ No newline at end of file From 923da3d4926256ad5ffde77dde2bbccb33fced52 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 29 Feb 2024 21:29:22 +0000 Subject: [PATCH 03/14] Enforce AttributeTargets.Class properly in the compiler --- .../CustomAttributes/AttributeUsage/AttributeUsage.fs | 1 + .../AttributeUsage/E_AttributeTargetIsClass.fs | 7 ++++++- .../AttributeUsage/E_AttributeTargetIsStruct.fs | 8 +++++++- tests/service/data/TestTP/ProvidedTypes.fs | 2 -- 4 files changed, 14 insertions(+), 4 deletions(-) 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 45d4b6789e9..e1c0628b338 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -329,6 +329,7 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 19, Col 3, Line 19, Col 14, "This attribute is not valid for use on this language element") (Error 842, Line 22, Col 11, Line 22, Col 22, "This attribute is not valid for use on this language element") (Error 842, Line 25, Col 3, Line 25, Col 25, "This attribute is not valid for use on this language element") + (Error 842, Line 32, Col 3, Line 32, Col 11, "This attribute is not valid for use on this language element") ] // SOURCE=MarshalAsAttribute.fs # MarshalAsAttribute.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs index 28da51fb5ab..90cc5c8ff89 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs @@ -26,4 +26,9 @@ type Class4 = class end type SemanticClassificationItem = val Range: int val Type: string - new((range, ty)) = { Range = range; Type = ty } \ No newline at end of file + new((range, ty)) = { Range = range; Type = ty } + +[] //AutoOpen is marked AttributeTargets.Class +type ILTableName(idx: int) = + member __.Index = idx + static member FromIndex n = ILTableName n \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs index 71fac8b8238..050907508f2 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs @@ -27,4 +27,10 @@ type Struct4 = struct end type SemanticClassificationItem = val Range: int val Type: string - new((range, ty)) = { Range = range; Type = ty } \ No newline at end of file + new((range, ty)) = { Range = range; Type = ty } + +[] //AutoOpen is marked AttributeTargets.Class so this should be an error +[] +type ILTableName(idx: int) = + member __.Index = idx + static member FromIndex n = ILTableName n \ No newline at end of file diff --git a/tests/service/data/TestTP/ProvidedTypes.fs b/tests/service/data/TestTP/ProvidedTypes.fs index 828235a0b9d..606ba52b3e2 100644 --- a/tests/service/data/TestTP/ProvidedTypes.fs +++ b/tests/service/data/TestTP/ProvidedTypes.fs @@ -3220,8 +3220,6 @@ module internal AssemblyReader = systemRuntimeScopeRef: ILScopeRef } override __.ToString() = "" - [] - [] type ILTableName(idx: int) = member __.Index = idx From 693da5eb5ee429da1aea7cc0a28efcccfbabed7a Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 1 Mar 2024 11:42:26 +0000 Subject: [PATCH 04/14] update tests --- src/Compiler/Checking/CheckDeclarations.fs | 4 ++-- tests/service/ProjectAnalysisTests.fs | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 534f9fd5f4b..fd35ae83ee9 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -2911,13 +2911,13 @@ module EstablishTypeDefinitionCores = match kind with | SynTypeDefnKind.Class -> if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnStructAndClasses) then - TcAttributes cenv envinner AttributeTargets.Class synAttrs |> ignore + TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore TFSharpClass | SynTypeDefnKind.Interface -> TFSharpInterface | SynTypeDefnKind.Delegate _ -> TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None)) | SynTypeDefnKind.Struct -> if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargetsOnStructAndClasses) then - TcAttributes cenv envinner AttributeTargets.Struct synAttrs |> ignore + TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore TFSharpStruct | _ -> error(InternalError("should have inferred tycon kind", m)) diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index b5324d5611b..5b8da7c30a3 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -2360,8 +2360,10 @@ let ``Test Project14 all symbols`` () = |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project14.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su) allUsesOfAllSymbols |> shouldEqual - [|("StructAttribute", "StructAttribute", "file1", ((4, 2), (4, 8)), - ["attribute"]); + [| + ("StructAttribute", "StructAttribute", "file1", ((4, 2), (4, 8)), ["attribute"]); + ("member .ctor", "StructAttribute", "file1", ((4, 2), (4, 8)), []) + ("StructAttribute", "StructAttribute", "file1", ((4, 2), (4, 8)), ["attribute"]); ("member .ctor", "StructAttribute", "file1", ((4, 2), (4, 8)), []); ("int", "int", "file1", ((5, 9), (5, 12)), ["type"]); ("int", "int", "file1", ((5, 9), (5, 12)), ["type"]); @@ -2514,14 +2516,14 @@ let ``Test Project16 all symbols`` () = |> Array.map (fun su -> su.Symbol.ToString(), su.Symbol.DisplayName, Project16.cleanFileName su.FileName, tups su.Range, attribsOfSymbolUse su, attribsOfSymbol su.Symbol) allUsesOfAllSymbols |> shouldEqual - [|("ClassAttribute", "ClassAttribute", "sig1", ((8, 6), (8, 11)), - ["attribute"], ["class"]); - ("member .ctor", "ClassAttribute", "sig1", ((8, 6), (8, 11)), [], - ["member"]); - ("ClassAttribute", "ClassAttribute", "sig1", ((12, 6), (12, 11)), - ["attribute"], ["class"]); - ("member .ctor", "ClassAttribute", "sig1", ((12, 6), (12, 11)), [], - ["member"]); + [|("ClassAttribute", "ClassAttribute", "sig1", ((8, 6), (8, 11)), ["attribute"], ["class"]); + ("member .ctor", "ClassAttribute", "sig1", ((8, 6), (8, 11)), [], ["member"]); + ("ClassAttribute", "ClassAttribute", "sig1", ((8, 6), (8, 11)), ["attribute"], ["class"]); + ("member .ctor", "ClassAttribute", "sig1", ((8, 6), (8, 11)), [], ["member"]); + ("ClassAttribute", "ClassAttribute", "sig1", ((12, 6), (12, 11)), ["attribute"], ["class"]); + ("member .ctor", "ClassAttribute", "sig1", ((12, 6), (12, 11)), [], ["member"]); + ("ClassAttribute", "ClassAttribute", "sig1", ((12, 6), (12, 11)), ["attribute"], ["class"]); + ("member .ctor", "ClassAttribute", "sig1", ((12, 6), (12, 11)), [], ["member"]); ("int", "int", "sig1", ((16, 19), (16, 22)), ["type"], ["abbrev"]); ("int", "int", "sig1", ((16, 33), (16, 36)), ["type"], ["abbrev"]); ("int", "int", "sig1", ((17, 25), (17, 28)), ["type"], ["abbrev"]); From 83a60d85a0066610b3f6e6456b14d8055c4e2fef Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 1 Mar 2024 12:09:25 +0000 Subject: [PATCH 05/14] Fix test --- .../DummyProviderForLanguageServiceTesting/ProvidedTypes.fs | 2 -- 1 file changed, 2 deletions(-) diff --git a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs index ae593e9961a..11aea7b24c9 100644 --- a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs +++ b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs @@ -2960,8 +2960,6 @@ namespace ProviderImplementation.ProvidedTypes.AssemblyReader systemRuntimeScopeRef: ILScopeRef } override _.ToString() = "" - [] - [] type ILTableName(idx: int) = member _.Index = idx From 504d7e3948745c72ee8b4c5b856adc796fba1887 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 1 Mar 2024 13:54:20 +0000 Subject: [PATCH 06/14] release-notes --- docs/release-notes/.FSharp.Compiler.Service/8.0.300.md | 1 + docs/release-notes/.Language/preview.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 5507157222e..a5ab7f9f2aa 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -14,6 +14,7 @@ * Allow calling method with both Optional and ParamArray. ([#PR 16688](https://github.com/dotnet/fsharp/pull/16688), [suggestions #1120](https://github.com/fsharp/fslang-suggestions/issues/1120)) * Fix release inline optimization, which leads to MethodAccessException if used with `assembly:InternalsVisibleTo`` attribute. ([Issue #16105](https://github.com/dotnet/fsharp/issues/16105), ([PR #16737](https://github.com/dotnet/fsharp/pull/16737)) * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) +* Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) ### Added diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index f39dd172561..06c6d26119f 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -9,6 +9,7 @@ * Allow extension methods without type attribute work for types from imported assemblies. ([PR #16368](https://github.com/dotnet/fsharp/pull/16368)) * Enforce AttributeTargets on let values and functions. ([PR #16692](https://github.com/dotnet/fsharp/pull/16692)) +* Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) ### Changed From 884827a482a7c76f562d657b37f9d1b55ef46f49 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 6 Mar 2024 16:41:30 +0000 Subject: [PATCH 07/14] Extend AutoOpenAttribute and RequireQualifiedAccessAttribute to use AttributeTargets.Struct --- src/FSharp.Core/prim-types.fs | 4 ++-- src/FSharp.Core/prim-types.fsi | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs index 346c1a64e0e..b7e4d187623 100644 --- a/src/FSharp.Core/prim-types.fs +++ b/src/FSharp.Core/prim-types.fs @@ -350,12 +350,12 @@ namespace Microsoft.FSharp.Core type RequiresExplicitTypeArgumentsAttribute() = inherit Attribute() - [] + [] [] type RequireQualifiedAccessAttribute() = inherit Attribute() - [] + [] [] type AutoOpenAttribute(path:string) = inherit Attribute() diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index dc4b9cc22dd..15c2b8c06a4 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -898,7 +898,7 @@ namespace Microsoft.FSharp.Core /// type require explicit qualified access. /// /// Attributes - [] + [] [] type RequireQualifiedAccessAttribute = inherit Attribute @@ -920,7 +920,7 @@ namespace Microsoft.FSharp.Core /// /// /// Attributes - [] + [] [] type AutoOpenAttribute = inherit Attribute From bcd2f1f98f288a11e1897d95ba59354d4caebfdb Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 6 Mar 2024 16:42:05 +0000 Subject: [PATCH 08/14] Put back AutoOpen and RequireQualifiedAccess --- src/Compiler/Service/SemanticClassification.fs | 1 + src/Compiler/Service/SemanticClassification.fsi | 1 + tests/service/data/TestTP/ProvidedTypes.fs | 1 + .../DummyProviderForLanguageServiceTesting/ProvidedTypes.fs | 1 + 4 files changed, 4 insertions(+) diff --git a/src/Compiler/Service/SemanticClassification.fs b/src/Compiler/Service/SemanticClassification.fs index 6053f996ece..6ebbb3c8ae0 100644 --- a/src/Compiler/Service/SemanticClassification.fs +++ b/src/Compiler/Service/SemanticClassification.fs @@ -58,6 +58,7 @@ type SemanticClassificationType = | TypeDef = 35 | Plaintext = 36 +[] [] type SemanticClassificationItem = val Range: range diff --git a/src/Compiler/Service/SemanticClassification.fsi b/src/Compiler/Service/SemanticClassification.fsi index 1fb4cf28df5..ce5d6d88aeb 100644 --- a/src/Compiler/Service/SemanticClassification.fsi +++ b/src/Compiler/Service/SemanticClassification.fsi @@ -49,6 +49,7 @@ type SemanticClassificationType = | TypeDef = 35 | Plaintext = 36 +[] [] type SemanticClassificationItem = val Range: range diff --git a/tests/service/data/TestTP/ProvidedTypes.fs b/tests/service/data/TestTP/ProvidedTypes.fs index 606ba52b3e2..9cd4c0dc0a2 100644 --- a/tests/service/data/TestTP/ProvidedTypes.fs +++ b/tests/service/data/TestTP/ProvidedTypes.fs @@ -3220,6 +3220,7 @@ module internal AssemblyReader = systemRuntimeScopeRef: ILScopeRef } override __.ToString() = "" + [] [] type ILTableName(idx: int) = member __.Index = idx diff --git a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs index 11aea7b24c9..e787194a7b6 100644 --- a/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs +++ b/vsintegration/tests/MockTypeProviders/DummyProviderForLanguageServiceTesting/ProvidedTypes.fs @@ -2960,6 +2960,7 @@ namespace ProviderImplementation.ProvidedTypes.AssemblyReader systemRuntimeScopeRef: ILScopeRef } override _.ToString() = "" + [] [] type ILTableName(idx: int) = member _.Index = idx From f70838421afd2ce0bc93d63d36409b50ff21e07b Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 6 Mar 2024 16:42:14 +0000 Subject: [PATCH 09/14] Update tests --- .../AttributeUsage/AttributeTargetsIsClass.fs | 26 ++++++++ .../AttributeTargetsIsStruct.fs | 23 ++++++++ .../AttributeUsage/AttributeUsage.fs | 59 ++++++++++++++----- .../E_AttributeTargetIsClass.fs | 13 +--- .../E_AttributeTargetIsStruct.fs | 13 +--- 5 files changed, 96 insertions(+), 38 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsClass.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsStruct.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsClass.fs new file mode 100644 index 00000000000..8f587dcf099 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsClass.fs @@ -0,0 +1,26 @@ +open System + +[] +type CustomClassAttribute() = + inherit Attribute() + +[] +type Class(x: int) = class end + +[] +[] +type Class2 = class end + +[] +type Class3() = class end + +[] +type SemanticClassificationItem = + val Range: int + val Type: string + new((range, ty)) = { Range = range; Type = ty } + +[] +type ILTableName(idx: int) = + member __.Index = idx + static member FromIndex n = ILTableName n diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsStruct.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsStruct.fs new file mode 100644 index 00000000000..9b64c7cb33f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeTargetsIsStruct.fs @@ -0,0 +1,23 @@ +open System + +[] +type CustomStructAttribute() = + inherit Attribute() + +[] +type Class(x: int) = struct end + +[] +[] +type Class2 = struct end + +[] +type SemanticClassificationItem = + val Range: int + val Type: string + new((range, ty)) = { Range = range; Type = ty } + +[] +type ILTableName(idx: int) = + member __.Index = idx + static member FromIndex n = ILTableName n 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 bb26d06e385..652755fd5cd 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs @@ -312,26 +312,36 @@ module CustomAttributes_AttributeUsage = |> withDiagnostics [ (Error 842, Line 12, Col 3, Line 12, Col 6, "This attribute is not valid for use on this language element") ] - - // SOURCE=E_AttributeTargetIsClass.fs # E_AttributeTargetIsClass.fs - [] - let ``E_AttributeTargetIsClass_fs`` compilation = + + // SOURCE=AttributeTargetIsStruct.fs # AttributeTargetIsStruct.fs + [] + let ``AttributeTargetIsStruct_fs`` compilation = compilation |> verifyCompile |> shouldSucceed - // SOURCE=E_AttributeTargetIsClass.fs # E_AttributeTargetIsClass.fs - [] - let ``E_AttributeTargetIsClass_fs preview`` compilation = + // SOURCE=AttributeTargetIsStruct.fs # AttributeTargetIsStruct.fs + [] + let ``AttributeTargetIsStruct_fs preview`` compilation = compilation |> withLangVersionPreview |> verifyCompile - |> shouldFail - |> withDiagnostics [ - (Error 842, Line 13, Col 3, Line 13, Col 15, "This attribute is not valid for use on this language element") - (Error 842, Line 19, Col 3, Line 19, Col 15, "This attribute is not valid for use on this language element") - (Error 842, Line 22, Col 10, Line 22, Col 22, "This attribute is not valid for use on this language element") - ] + |> shouldSucceed + + // SOURCE=AttributeTargetIsClass.fs # AttributeTargetIsClass.fs + [] + let ``AttributeTargetIsClass_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=AttributeTargetIsClass.fs # AttributeTargetIsClass.fs + [] + let ``AttributeTargetIsClass_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldSucceed // SOURCE=E_AttributeTargetIsStruct.fs # E_AttributeTargetIsStruct.fs [] @@ -351,8 +361,27 @@ module CustomAttributes_AttributeUsage = (Error 842, Line 13, Col 3, Line 13, Col 14, "This attribute is not valid for use on this language element") (Error 842, Line 19, Col 3, Line 19, Col 14, "This attribute is not valid for use on this language element") (Error 842, Line 22, Col 11, Line 22, Col 22, "This attribute is not valid for use on this language element") - (Error 842, Line 25, Col 3, Line 25, Col 25, "This attribute is not valid for use on this language element") - (Error 842, Line 32, Col 3, Line 32, Col 11, "This attribute is not valid for use on this language element") + (Error 842, Line 25, Col 3, Line 25, Col 14, "This attribute is not valid for use on this language element") + ] + + // SOURCE=E_AttributeTargetIsClass.fs # E_AttributeTargetIsClass.fs + [] + let ``E_AttributeTargetIsClass_fs`` compilation = + compilation + |> verifyCompile + |> shouldSucceed + + // SOURCE=E_AttributeTargetIsClass.fs # E_AttributeTargetIsClass.fs + [] + let ``E_AttributeTargetIsClass_fs preview`` compilation = + compilation + |> withLangVersionPreview + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 842, Line 13, Col 3, Line 13, Col 15, "This attribute is not valid for use on this language element") + (Error 842, Line 19, Col 3, Line 19, Col 15, "This attribute is not valid for use on this language element") + (Error 842, Line 22, Col 10, Line 22, Col 22, "This attribute is not valid for use on this language element") ] // SOURCE=MarshalAsAttribute.fs # MarshalAsAttribute.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs index 90cc5c8ff89..845b7d1762f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsClass.fs @@ -20,15 +20,4 @@ type Class2(x: int) = class end type Class3(x: int) = class end [] -type Class4 = class end - -[] //RequireQualifiedAccess is marked AttributeTargets.Class -type SemanticClassificationItem = - val Range: int - val Type: string - new((range, ty)) = { Range = range; Type = ty } - -[] //AutoOpen is marked AttributeTargets.Class -type ILTableName(idx: int) = - member __.Index = idx - static member FromIndex n = ILTableName n \ No newline at end of file +type Class4 = class end \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs index 050907508f2..ace0b6a5c39 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/E_AttributeTargetIsStruct.fs @@ -22,15 +22,6 @@ type Struct2(x: int) = struct end [] type Struct4 = struct end -[] //RequireQualifiedAccess is marked AttributeTargets.Class. so this should be an error -[] -type SemanticClassificationItem = - val Range: int - val Type: string - new((range, ty)) = { Range = range; Type = ty } - -[] //AutoOpen is marked AttributeTargets.Class so this should be an error +[] [] -type ILTableName(idx: int) = - member __.Index = idx - static member FromIndex n = ILTableName n \ No newline at end of file +type Struct5 = struct end \ No newline at end of file From 51a6d10fa2f7edea7bb49b2d4746bb66e1e5a2bb Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 6 Mar 2024 16:51:27 +0000 Subject: [PATCH 10/14] Release notes --- docs/release-notes/.FSharp.Core/8.0.300.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md index 7c3911ae98f..bf6c59daa44 100644 --- a/docs/release-notes/.FSharp.Core/8.0.300.md +++ b/docs/release-notes/.FSharp.Core/8.0.300.md @@ -6,3 +6,4 @@ ### Fixed * Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568)) +* Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) From 0deaa4d9326a4d2e35a65cb978dec50b5a0bf5a0 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 8 Mar 2024 17:33:22 +0000 Subject: [PATCH 11/14] release notes --- docs/release-notes/.FSharp.Core/8.0.300.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md index bf6c59daa44..60b25705745 100644 --- a/docs/release-notes/.FSharp.Core/8.0.300.md +++ b/docs/release-notes/.FSharp.Core/8.0.300.md @@ -6,4 +6,4 @@ ### Fixed * Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568)) -* Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) +* Enforce AttributeTargets on structs and classes. Also update `RequireQualifiedAccessAttribute` and `AutoOpenAttribute` to use `AttributeTargets.Struct` ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) \ No newline at end of file From db5ccee49b14fb79a6c69e07a617473831140dca Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Mon, 11 Mar 2024 14:17:13 +0100 Subject: [PATCH 12/14] Extend attributes targets --- src/FSharp.Core/fslib-extra-pervasives.fs | 2 +- src/FSharp.Core/fslib-extra-pervasives.fsi | 2 +- src/FSharp.Core/prim-types.fs | 14 +++++++------- src/FSharp.Core/prim-types.fsi | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/FSharp.Core/fslib-extra-pervasives.fs b/src/FSharp.Core/fslib-extra-pervasives.fs index b62d5b16eb8..b5cf5dee3af 100644 --- a/src/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/FSharp.Core/fslib-extra-pervasives.fs @@ -363,7 +363,7 @@ type MeasureOne = class end -[] +[] type TypeProviderAttribute() = inherit System.Attribute() diff --git a/src/FSharp.Core/fslib-extra-pervasives.fsi b/src/FSharp.Core/fslib-extra-pervasives.fsi index ffd6f6f6a00..97120245f87 100644 --- a/src/FSharp.Core/fslib-extra-pervasives.fsi +++ b/src/FSharp.Core/fslib-extra-pervasives.fsi @@ -385,7 +385,7 @@ namespace Microsoft.FSharp.Core.CompilerServices type MeasureOne /// Place on a class that implements ITypeProvider to extend the compiler - [] + [] type TypeProviderAttribute = inherit System.Attribute diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs index b7e4d187623..26bbb1294cb 100644 --- a/src/FSharp.Core/prim-types.fs +++ b/src/FSharp.Core/prim-types.fs @@ -104,7 +104,7 @@ namespace Microsoft.FSharp.Core type CLIMutableAttribute() = inherit Attribute() - [] + [] [] type AutoSerializableAttribute(value:bool) = inherit Attribute() @@ -127,19 +127,19 @@ namespace Microsoft.FSharp.Core type ReferenceEqualityAttribute() = inherit Attribute() - [] + [] [] type StructuralComparisonAttribute() = inherit Attribute() - [] + [] [] type StructuralEqualityAttribute() = inherit Attribute() [] + AttributeTargets.Enum, AllowMultiple=false)>] [] type NoEqualityAttribute() = inherit Attribute() @@ -161,9 +161,9 @@ namespace Microsoft.FSharp.Core type NoComparisonAttribute() = inherit Attribute() - [] + [] [] type ReflectedDefinitionAttribute(includeValue: bool) = inherit Attribute() diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index 15c2b8c06a4..fc2b4d756a9 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -129,7 +129,7 @@ namespace Microsoft.FSharp.Core /// for use at runtime. /// /// Attributes - [] + [] [] type ReflectedDefinitionAttribute = inherit Attribute @@ -385,7 +385,7 @@ namespace Microsoft.FSharp.Core /// 'System.Object.GetHashCode()' for the type. /// /// Attributes - [] + [] [] type StructuralEqualityAttribute = inherit Attribute @@ -398,7 +398,7 @@ namespace Microsoft.FSharp.Core /// automatic generation of implementations for 'System.IComparable' for the type. /// /// Attributes - [] + [] [] type StructuralComparisonAttribute = inherit Attribute @@ -604,7 +604,7 @@ namespace Microsoft.FSharp.Core /// type Serializable by default. /// /// Attributes - [] + [] [] type AutoSerializableAttribute = inherit Attribute From 7c98bac563f39e75f4145af0707e206ff003280a Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Mon, 11 Mar 2024 14:34:35 +0100 Subject: [PATCH 13/14] Update prim-types.fs --- src/FSharp.Core/prim-types.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharp.Core/prim-types.fs b/src/FSharp.Core/prim-types.fs index 26bbb1294cb..777a31b8e15 100644 --- a/src/FSharp.Core/prim-types.fs +++ b/src/FSharp.Core/prim-types.fs @@ -104,7 +104,7 @@ namespace Microsoft.FSharp.Core type CLIMutableAttribute() = inherit Attribute() - [] + [] [] type AutoSerializableAttribute(value:bool) = inherit Attribute() From ca453327963dd2d287d57de3edbf5e6f13348e41 Mon Sep 17 00:00:00 2001 From: Petr Date: Wed, 13 Mar 2024 17:25:33 +0100 Subject: [PATCH 14/14] Update 8.0.300.md --- docs/release-notes/.FSharp.Compiler.Service/8.0.300.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index ad42270d3d8..83b2c864908 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -17,7 +17,6 @@ * Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764)) * Disallow using base to invoke an abstract base method. ([Issue #13926](https://github.com/dotnet/fsharp/issues/13926), [PR #16773](https://github.com/dotnet/fsharp/pull/16773)) * Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790)) -* Fix broken code completion after a record type declaration ([PR #16813]([Title](https://github.com/dotnet/fsharp/pull/16813))) * Parser: fix pattern range for idents with trivia ([PR #16824](https://github.com/dotnet/fsharp/pull/16824)) * Fix broken code completion after a record type declaration ([PR #16813](https://github.com/dotnet/fsharp/pull/16813))