fsharp icon indicating copy to clipboard operation
fsharp copied to clipboard

Attribute defined on second method of property is ignored

Open BoundedChenn31 opened this issue 4 years ago • 1 comments

F# allows to declare get and set parts of property separately and in any order, like so

member _.A with get () = internalValue
member _.A with set (value) = internalValue <- value

However, attributes that are defined on second part (get or set, doesn't matter) are ignored.

Repro steps

  1. Create project with the following code or use sharplab:
type Foo() =
  let mutable internalValue = 1
  member _.A with get () = internalValue
  [<System.Obsolete>] member _.A with set (v: int) = internalValue <- v
  1. Compile and observe IL

Expected behavior

Property A is marked as obsolete or compiler warning if current behavior is intentional.

Actual behavior

Property A is not obsolete. Attribute is missing from IL.

Known workarounds Combined syntax member _.Prop with get () = 1 and set (v: int) = () or attribute on first method of property.

Related information dotnet version: 5.0.202

BoundedChenn31 avatar May 06 '21 06:05 BoundedChenn31

@vzarytovskii I looked at this while I was working on #13257 and here are my findings in case we wanted to fix this :)

  • Currently F# is not consistent with C#
type Foo() =
  let mutable internalValue = 1
  member _.A with get () = internalValue
  [<System.Obsolete>] member _.A with set (v: int) = internalValue <- v

let foo = new Foo()
let value1 = foo.A //  warning NOT expected .  Consistent with C#
let value2 = foo.A <- 12 //warning expected . Consistent with C#

type Foo() =
  let mutable internalValue = 1
  [<System.Obsolete>] member _.A with get () = internalValue
  member _.A with set (v: int) = internalValue <- v

let foo = new Foo()
let value1 = foo.A //  warning expected .  Consistent with C#
let value2 = foo.A <- 12 // warning NOT expected consistent with C#

type Foo() =
  let mutable internalValue = 1
  [<System.Obsolete>] member _.A with get () = internalValue
  [<System.Obsolete>] member _.A with set (v: int) = internalValue <- v

let foo = new Foo()
let value1 = foo.A //  warning expected .  Consistent with C#
let value2 = foo.A <- 12 // warning expected(But none was shown)  Inconsistent with C#

C# SharpLab

F# ShapLab

edgarfgp avatar Jul 14 '22 10:07 edgarfgp

This is fixed. See tests https://github.com/dotnet/fsharp/blob/ee46275f9f302cc03dbcdf691e444282474856e4/tests/FSharp.Compiler.ComponentTests/Language/ObsoleteAttributeCheckingTests.fs#L630

edgarfgp avatar Mar 28 '24 15:03 edgarfgp