The F# 9 release introduced attribute targets enforcement on let binding, as illustrated by the following example from the blog:
[<Fact>]
let ``this test always fails`` =
Assert.True(false)
In this snippet, an attribute intended for methods is applied on a value bindings, thus leading to an error. The opposite holds as well:
[<FieldOnly>] // Suppose AttributeTargets.Field on it.
let foo () = whatever
However, problem arises when the value binding decorated by the attribute is not in fact a field. In cases of extremely simple values
open System
[<AttributeUsage(AttributeTargets.Field)>]
type FieldOnly() =
inherit Attribute()
[<FieldOnly>]
let foo = 0
open System
[<AttributeUsage(AttributeTargets.Field)>]
type FieldOnly() =
inherit Attribute()
[<FieldOnly>]
let foo = None
the value binding compiles to a property without a backing field, so the attribute intended for fields is actually applied on a property.
I think this might lead to some subtle bugs in reflective programs, such as a dynamic script loader. Is there any fix to it? Or is it worth a GitHub issue?