Skip to content

F# compiler does not enforce attribute targets #8547

Description

@njlr

Compile this code:

open System

[<AttributeUsage(AttributeTargets.Method)>]
type MethodOnlyAttribute() = 
  inherit System.Attribute()

[<MethodOnly>]
let abc () =
  "abc"

[<MethodOnly>]
let def =
  "def"

Expected behavior

Compilation should fail because def is not a method; it is a string.

Actual behavior

The code compiles.

Known workarounds

Take care not to use attributes incorrectly.

Related information

#4460 is not quite the same, but a fix will probably touch the same code.

  • Operating system: Linux
  • .NET Runtime kind: .NET Core, Fable
  • Editing Tools: Visual Studio Code

Activity

  1. cartermp commented on Feb 11, 2020

    @cartermp
    Contributor

    So this one is kinda funky. F# functions emit as methods, so it's technically correct that you can use MethodOnly on an F# function.

    However, in F# semantics there is a very loose distinction (often no distinction) between F# functions and values. F# supports "normal" functions like let add x y = x + y, but also function values like this to support partial application:

    let add x = fun y -> x + y
    let add' x y = x + y

    And you can apply the attribute to that as well. The typechecker doesn't distinguish between the two functions (at least not how you might expect). The consequence of that is you can apply the attribute to something that emits as a property.

    I would argue that this is a bug, but fixing it would also be a breaking change, so the best we can do is emit a warning.

  2. added this to the Backlog milestone on Feb 11, 2020
  3. twaalewijn commented on Jul 4, 2020

    @twaalewijn

    Does the same funkiness apply for AttributeTargets that target types?

    Such as:

    • AttributeTargets.Class
    • AttributeTargets.Interface
    • AttributeTargets.Struct

    I ran into this while consuming a C# library (I only have limited F# experience) that had attributes with these targets.
    E.g. the following situations compile but some wouldn't in C#:

    open System
    
    [<AttributeUsage(AttributeTargets.Class)>]
    type ClassTargetAttribute() =
        inherit Attribute()
    
    [<AttributeUsage(AttributeTargets.Interface)>]
    type InterfaceTargetAttribute() =
        inherit Attribute()
    
    [<AttributeUsage(AttributeTargets.Struct)>]
    type StructTargetAttribute() =
        inherit Attribute()
    
    [<ClassTarget>] // Valid
    [<InterfaceTarget>] // Invalid
    [<StructTarget>] // Invalid
    type C() =
        member _.M() = ()
    
    [<ClassTarget>] // Invalid
    [<InterfaceTarget>] // Valid
    [<StructTarget>] // Invalid
    type I =
        abstract member prop: string
        
    [<ClassTarget>] // Valid
    [<InterfaceTarget>] // Invalid
    [<StructTarget>] // Invalid
    type RecRef = {
        prop: string
    }
    
    [<ClassTarget>] // Invalid
    [<InterfaceTarget>] // Invalid
    [<StructTarget>] // Valid
    [<Struct>]
    type RecStruct = {
        prop: string
    }
  4. dsyme commented on Aug 31, 2020

    @dsyme
    Contributor

    Yes, this should give a warning or error that the attribute is not applicable to def.

    I will also list this as a spec clarification issue in fsharp/fsharp.org#841 - we should indicate for each language element exactly which attribute targets are allowed. Some parts of the spec do record this but not all.

  5. added
    Impact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.
    on Aug 31, 2020
  6. added
    Area-Compiler-CheckingType checking, attributes and all aspects of logic checking
    and removed on Apr 4, 2022
  7. ly29 commented on Jun 9, 2022

    @ly29

    This trips us from time to time while writing tests in xunit where people forget to put unit after the let function

        [<Fact>]
        let ``When receiving should`` = ...
    

    vs

        [<Fact>]
        let ``When receiving should`` () = ...
    

    Would be very helpful with a compiler warning/error.

  8. edgarfgp commented on Feb 19, 2024

    @edgarfgp
    Contributor

    Yes, this should give a warning or error that the attribute is not applicable to def.

    I will also list this as a spec clarification issue in fsharp/fsfoundation#841 - we should indicate for each language element exactly which attribute targets are allowed. Some parts of the spec do record this but not all.

    Im adding the warning for this. @vzarytovskii @dsyme any plans on updating the lang specification about this? Want to help fixing all this inconsistencies but it is hard without knowing this

  9. vzarytovskii commented on Feb 19, 2024

    @vzarytovskii
    Member

    Yes, this should give a warning or error that the attribute is not applicable to def.

    I will also list this as a spec clarification issue in fsharp/fsfoundation#841 - we should indicate for each language element exactly which attribute targets are allowed. Some parts of the spec do record this but not all.

    Im adding the warning for this. @vzarytovskii @dsyme any plans on updating the lang specification about this? Want to help fixing all this inconsistencies but it is hard without knowing this

    It should be an rfc, since we treat those as additions to specification.

  10. edgarfgp commented on Feb 19, 2024

    @edgarfgp
    Contributor

    Yes, this should give a warning or error that the attribute is not applicable to def.

    I will also list this as a spec clarification issue in fsharp/fsfoundation#841 - we should indicate for each language element exactly which attribute targets are allowed. Some parts of the spec do record this but not all.

    Im adding the warning for this. @vzarytovskii @dsyme any plans on updating the lang specification about this? Want to help fixing all this inconsistencies but it is hard without knowing this

    It should be an rfc, since we treat those as additions to specification.

    Yes RFC would be good to have that documented there . I can see 10+ issues related to AttributesTargets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-Compiler-CheckingType checking, attributes and all aspects of logic checkingBugImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions