fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Attribute targets on records

Open edgarfgp opened this issue 1 year ago • 4 comments

Follow up: https://github.com/dotnet/fsharp/pull/17173

Records compiles down to a class or struct sharplab.

This PR enforces the new rules on records.

Old rules

  • AttributeTargets.Class
  • AttributeTargets.Interface
  • AttributeTargets.Delegate
  • AttributeTargets.Struct
  • AttributeTargets.Enum

New Rules

  • AttributeTargets.Class
  • AttributeTargets.Struct when using [<Struct>]
  • AttributeTargets.Class ||| AttributeTargets.Struct when using [<RequireQualifiedAccess>]

Before sharplab

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

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

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

 [<InterfaceTarget>] // Does not fail. It should
 [<StructTarget>] // Does not fail. It should
 [<ClassTarget>]
 type Record = { Prop: string }

 [<ClassTarget>] // Does not fail. It should
 [<InterfaceTarget>] // Does not fail. It should
 [<Struct>]
type StructRecord = { Prop: string }

After

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

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

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

 [<InterfaceTarget>] // Fails as expected
 [<StructTarget>] // Fails as expected
 [<ClassTarget>]
 type Record = { Prop: string }

 [<ClassTarget>] // Fails as expected
 [<InterfaceTarget>] // Fails as expected
 [<Struct>]
type StructRecord = { Prop: string }

Checklist

  • [x] Test cases added
  • [x] Release notes entry updated

edgarfgp avatar May 21 '24 20:05 edgarfgp

:heavy_exclamation_mark: Release notes required


:white_check_mark: Found changes and release notes in following paths:

Change path Release notes path Description
src/FSharp.Core docs/release-notes/.FSharp.Core/8.0.400.md
src/Compiler docs/release-notes/.FSharp.Compiler.Service/8.0.400.md

github-actions[bot] avatar May 21 '24 20:05 github-actions[bot]

Ready for review

edgarfgp avatar Jun 11 '24 14:06 edgarfgp

/azp run

psfinaki avatar Jun 14 '24 08:06 psfinaki

Azure Pipelines successfully started running 2 pipeline(s).

azure-pipelines[bot] avatar Jun 14 '24 08:06 azure-pipelines[bot]

[!CAUTION] Repository is on lockdown for maintenance, all merges are on hold.

github-actions[bot] avatar Jul 03 '24 15:07 github-actions[bot]

Can you explain the RequireQualifiedAccess reasoning here, maybe even in the comment as part of code?

Is it only a temporary need caused by new compiler + old FSharp.Core combination, eventually to be removed?

@T-Gro So the check for RequireQualifiedAccess is not needed at all. Turns out that when you use dotnet build on FSharp.Compiler.Service it uses the FSharp.Core nuget as opposed to the project reference and that is why my unit test was failing locally.

Thanks for the review

edgarfgp avatar Jul 04 '24 05:07 edgarfgp

Thanks! Appreciate your consistent and meticulous approach. Do you see the light at the end of the attributes tunnel?

Yes. I have 2 more PRs and then a RFC

edgarfgp avatar Jul 04 '24 13:07 edgarfgp