Repository navigation
F# compiler does not enforce attribute targets #8547
Description
Activity
So this one is kinda funky. F# functions emit as methods, so it's technically correct that you can use
MethodOnlyon 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.
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 }
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.
Reacted by Abel Braaksma and ly29- addedImpact-Medium(Internal MS Team use only) Describes an issue with moderate impact on existing code.(Internal MS Team use only) Describes an issue with moderate impact on existing code.
on Aug 31, 2020 - addedArea-Compiler-CheckingType checking, attributes and all aspects of logic checkingType checking, attributes and all aspects of logic checkingand removed
on Apr 4, 2022 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.
Reacted by njlrYes, 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
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, 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
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Compile this code:
Expected behavior
Compilation should fail because
defis not a method; it is astring.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.