Skip to content
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
2 changes: 1 addition & 1 deletion docs/release-notes/.FSharp.Compiler.Service/8.0.400.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* Generate new `Equals` overload to avoid boxing for structural comparison ([PR #16857](https://github.com/dotnet/fsharp/pull/16857))

### Changed

* Enforce `AttributeTargets.Interface` ([PR #17173](https://github.com/dotnet/fsharp/pull/17173))
* Minor compiler perf improvements. ([PR #17130](https://github.com/dotnet/fsharp/pull/17130))
* Improve error of Active Pattern case Argument Count Not Match ([PR #16846](https://github.com/dotnet/fsharp/pull/16846))
* AsyncLocal diagnostics context. ([PR #16779](https://github.com/dotnet/fsharp/pull/16779))
Expand Down
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Core/8.0.400.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
### Changed

* Cache delegate in query extensions. ([PR #17130](https://github.com/dotnet/fsharp/pull/17130))
* Update `AllowNullLiteralAttribute` to also use `AttributeTargets.Interface` ([PR #17173](https://github.com/dotnet/fsharp/pull/17173))
5 changes: 4 additions & 1 deletion src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2912,7 +2912,10 @@ module EstablishTypeDefinitionCores =
if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
TFSharpClass
| SynTypeDefnKind.Interface -> TFSharpInterface
| SynTypeDefnKind.Interface ->
if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Interface synAttrs |> ignore
TFSharpInterface
| SynTypeDefnKind.Delegate _ ->
if g.langVersion.SupportsFeature(LanguageFeature.EnforceAttributeTargets) then
TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Delegate synAttrs |> ignore
Expand Down
2 changes: 1 addition & 1 deletion src/FSharp.Core/prim-types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ namespace Microsoft.FSharp.Core
type ComparisonConditionalOnAttribute() =
inherit Attribute()

[<AttributeUsage(AttributeTargets.Class, AllowMultiple=false)>]
[<AttributeUsage(AttributeTargets.Class ||| AttributeTargets.Interface, AllowMultiple=false)>]
[<Sealed>]
type AllowNullLiteralAttribute(value: bool) =
inherit Attribute()
Expand Down
2 changes: 1 addition & 1 deletion src/FSharp.Core/prim-types.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ namespace Microsoft.FSharp.Core
/// interface types.</summary>
///
/// <category>Attributes</category>
[<AttributeUsage (AttributeTargets.Class,AllowMultiple=false)>]
[<AttributeUsage (AttributeTargets.Class ||| AttributeTargets.Interface, AllowMultiple=false)>]
[<Sealed>]
type AllowNullLiteralAttribute =
inherit Attribute
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
open System

[<AttributeUsage(AttributeTargets.Interface)>]
type CustomInterfaceAttribute() =
inherit Attribute()

[<CustomInterface>]
type IFoo = interface end

[<CustomInterface>]
type IFoo2 =
abstract A :int

[<CustomInterface>]
[<Interface>]
type IFoo3 =
abstract A :int
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,13 @@ module CustomAttributes_AttributeUsage =
|> verifyCompile
|> shouldSucceed

// SOURCE=E_AttributeTargetIsClass01.fs # E_AttributeTargetIsClass01.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsClass01.fs"|])>]
let ``E_AttributeTargetIsClass01_fs`` compilation =
compilation
|> verifyCompile
|> shouldSucceed

// SOURCE=E_AttributeTargetIsClass.fs # E_AttributeTargetIsClass.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsClass.fs"|])>]
let ``E_AttributeTargetIsClass_fs preview`` compilation =
Expand All @@ -363,6 +370,18 @@ module CustomAttributes_AttributeUsage =
(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_AttributeTargetIsClass01.fs # E_AttributeTargetIsClass01.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsClass01.fs"|])>]
let ``E_AttributeTargetIsClass01_fs preview`` compilation =
compilation
|> withLangVersionPreview
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 842, Line 7, Col 3, Line 7, Col 18, "This attribute is not valid for use on this language element")
(Error 842, Line 10, Col 10, Line 10, Col 25, "This attribute is not valid for use on this language element")
]

// SOURCE=MarshalAsAttribute.fs # MarshalAsAttribute.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"MarshalAsAttribute.fs"|])>]
Expand Down Expand Up @@ -583,4 +602,40 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
"""
|> withLangVersionPreview
|> compile
|> shouldSucceed
|> shouldSucceed

// SOURCE=AttributeTargetsIsInterface.fs # AttributeTargetsIsInterface.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"AttributeTargetsIsInterface.fs"|])>]
let ``AttributeTargetsIsInterface_fs`` compilation =
compilation
|> verifyCompile
|> shouldSucceed

// SOURCE=AttributeTargetsIsInterface.fs # AttributeTargetsIsInterface.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"AttributeTargetsIsInterface.fs"|])>]
let ``AttributeTargetsIsInterface_fs preview`` compilation =
compilation
|> withLangVersionPreview
|> verifyCompile
|> shouldSucceed

// SOURCE=E_AttributeTargetIsInterface.fs # E_AttributeTargetIsInterface.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsInterface.fs"|])>]
let ``E_AttributeTargetIsInterface_fs`` compilation =
compilation
|> verifyCompile
|> shouldSucceed

// SOURCE=E_AttributeTargetIsInterface.fs # E_AttributeTargetIsInterface.fs
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"E_AttributeTargetIsInterface.fs"|])>]
let ``E_AttributeTargetIsInterface_fs preview`` compilation =
compilation
|> withLangVersionPreview
|> verifyCompile
|> shouldFail
|> withDiagnostics [
(Error 842, Line 11, Col 3, Line 11, Col 14, "This attribute is not valid for use on this language element")
(Error 842, Line 14, Col 3, Line 14, Col 15, "This attribute is not valid for use on this language element")
(Error 842, Line 18, Col 3, Line 18, Col 14, "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")
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
open System

[<AttributeUsage(AttributeTargets.Interface)>]
type CustomInterfaceAttribute() =
inherit Attribute()

[<CustomInterface>]
type Class(x: int) = class end

[<Class; CustomInterface>]
type Class3 = class end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
open System

[<AttributeUsage(AttributeTargets.Struct)>]
type CustomStructAttribute() =
inherit Attribute()

[<AttributeUsage(AttributeTargets.Class)>]
type CustomClassAttribute() =
inherit Attribute()

[<CustomClass>]
type IFoo = interface end

[<CustomStruct>]
type IFoo2 =
abstract A :int

[<CustomClass>]
[<CustomStruct>]
[<Interface>]
type IFoo3 =
abstract A :int
31 changes: 16 additions & 15 deletions vsintegration/src/FSharp.ProjectSystem.FSharp/Project.fs
Original file line number Diff line number Diff line change
Expand Up @@ -158,21 +158,22 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
member this.Advise(callbackOwnerKey, callback) =
notificationsDict.[callbackOwnerKey] <- callback

// Used to get us sorted appropriately with the other MSFT products in the splash screen and about box
[<Guid("591E80E4-5F44-11d3-8BDC-00C04F8EC28C")>]
[<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>]
[<ComImport>]
[<Interface>]
[<ComVisible(true)>]
[<System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)>]
type public IVsMicrosoftInstalledProduct =
inherit IVsInstalledProduct
abstract IdBmpSplashM : byref<uint32> -> unit
abstract OfficialNameM : on : byref<string> -> unit
abstract ProductIDM : pid : byref<string> -> unit
abstract ProductDetailsM : pd : byref<string> -> unit
abstract IdIcoLogoForAboutboxM : byref<uint32> -> unit
abstract ProductRegistryName : prn : byref<string> -> unit
// // Used to get us sorted appropriately with the other MSFT products in the splash screen and about box
// [<Guid("591E80E4-5F44-11d3-8BDC-00C04F8EC28C")>]
// [<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>]
// [<ComImport>]
// [<ComVisible(true)>]
// [<System.Runtime.InteropServices.ClassInterface(ClassInterfaceType.None)>]
// [<AbstractClass>]
// type public IVsMicrosoftInstalledProduct =
// interface IVsInstalledProduct
//
// abstract IdBmpSplashM : byref<uint32> -> unit
// abstract OfficialNameM : on : byref<string> -> unit
// abstract ProductIDM : pid : byref<string> -> unit
// abstract ProductDetailsM : pd : byref<string> -> unit
// abstract IdIcoLogoForAboutboxM : byref<uint32> -> unit
// abstract ProductRegistryName : prn : byref<string> -> unit

exception internal ExitedOk
exception internal ExitedWithError
Expand Down