-
Notifications
You must be signed in to change notification settings - Fork 798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
F# 9 changes the validation of attribute usage targets for union cases. #18298
Comments
This was done as part of fsharp/fslang-suggestions#1375 , via a series of changes implemented by @edgarfgp . It has been indeed intentional to rectify a prior lack of enforcement. Unrestricted attribute would fit here best, but I assume that is not an option? |
Due to the lowering differences, the attribute targets are branched based on the numbers of fields:
|
@eiriktsarpalis are you using open System.Runtime.Serialization
type CartEvent =
| [<DataMember(Name = "cartCreated")>] CartCreated
Yes
open System
[<AttributeUsage(AttributeTargets.Property, AllowMultiple = false)>]
type PropertyOnlyAttribute() =
inherit Attribute()
[<AttributeUsage(AttributeTargets.Method, AllowMultiple = false)>]
type MethodOnlyAttribute() =
inherit Attribute()
[<AttributeUsage(AttributeTargets.Property ||| AttributeTargets.Method, AllowMultiple = false)>]
type PropertyAndMethodAttribute()
= inherit Attribute()
type CartEvent =
| [<PropertyOnly>] CartCreated
| [<MethodOnly>] CartUpdated of int
| [<PropertyAndMethod>] CartDeleted of int |
Does the above workaround still result in the custom attribute being reported when I call
Yes |
I believe so. If you run let a =
typeof<CartEvent>
|> FSharpType.GetUnionCases
|> Array.map (fun x -> x.GetCustomAttributes()) You will get. val a: obj array array =
[|[|FSI_0007+ProperlyOnlyAttribute;
Microsoft.FSharp.Core.CompilationMappingAttribute|];
[|FSI_0007+MethodOnlyAttribute;
Microsoft.FSharp.Core.CompilationMappingAttribute|];
[|FSI_0007+PropertyAndMethodAttribute;
Microsoft.FSharp.Core.CompilationMappingAttribute|]|] |
Do we need a dedicated docs section about attributes on unions and their cases perharps? |
While I get why each of the union case arities are mapped to
|
If DataMember is capable on support symbols beyond its attribute targets, wouldn't it then be possible to change it's declaration? If there are libraries that do support invalid combinations of symbols and attribute targets, I think we could go with an opt-in way to trigger warnings instead of errors. |
Types under System.Runtime.Serialization are considered legacy nowadays and we try not to make any changes to them. Apart from that though |
I don't want us to mix up two things when coming up with a solution:
Allowing |
It would not, but it's probably not the end of the world. |
We might re-think attributes on DUs (and how they are lowered) in the context of C# unions as well, assuming they will also have a similar situation of having >1 lowering schemes for 1 syntactical construct. @edgarfgp : Do you have any idea on how to make |
Like other OSS Libraries have done so far:
Before F#9 the AttributeTarget analysis was non existent. So now we are doing the "right thing" but I understand that not all people would be able/desire to update there libraries. |
Wouldn't a side-effect of that be that the attributes can now be applied to properties and methods outside of unions? |
Pretty sure that older versions were rejecting |
I think so. I guess it was almost non existent then :) |
Orthogonal idea: |
We're seeing this on
https://github.com/ionide/FSharp.Analyzers.SDK/actions/runs/13298889551/job/37136571174#step:4:51 type Arguments =
| Project of string list
| Analyzers_Path of string list
| [<EqualsAssignment; AltCommandLine("-p:"); AltCommandLine("-p")>] Property of string * string |
@TheAngryByrd i believe Argu updated the attribute targets in 6.2.4 https://github.com/fsprojects/Argu/releases/tag/6.2.4 |
I have issues with struct unions and [<Struct>]
[<RequireQualifiedAccess>]
type GlobalTime =
| Timestamp of MicroTime
| Infinity This should be valid or am I missing something? Wasn't sure if I should open another issue for this. |
@hyazinthh What is the error reported in your case.?. |
@edgarfgp it's the same FS0842 error message. Thanks for the FSharp.Core hint, seems like this only happens when you build against a FSharp.Core version before 8.0.300. We usually target the lowest possible version of FSharp.Core in our libraries to avoid conflicts with other third-party libraries that may force an older specific version. Currently, we target 8.0.100 so updating should be fine. Yet, this is pretty unexpected behavior. |
The attributes and their targets have a special position - even though they ship as part of the runtime library (FSharp.Core), the targets of the build-in attributes are needed at compile-time. In this specific scenario, it should be possible for you to built against a higher FSharp.Core, and let apps pin down a lower one. (but it is of course dangerous for using other possibly new/updated APIs in FSharp.Core) |
Just another record of someone encountering the breaking change above. I can work around all of it except the |
Yeah this definitely would be a better way of handling this. I would be ok to tackle this at some point before version 10 |
I noticed the following regression when trying to build an old F# project using the .NET 9 sdk. The following code
now fails to compile with the error
Technically, this error is correct because
DataMemberAttribute
specifiesAttributeTarget.Field ||| AttributeTarget.Property
however this is breaking a common pattern used when serializing events modelled as discriminated unions.So I have the following questions:
AttributeTarget
should library authors be specifying for attributes intended for application to union cases?cc @bartelink
The text was updated successfully, but these errors were encountered: