Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/8.0.300.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* Enforce AttributeTargets on enums ([PR #16887](https://github.com/dotnet/fsharp/pull/16887))
* Completion: fix for unfinished record field decl ([PR #16893](https://github.com/dotnet/fsharp/pull/16893))
* Enforce AttributeTargets on delegates ([PR #16891](https://github.com/dotnet/fsharp/pull/16891))
* Obsolete attribute is ignored in constructor property assignment ([PR #16900](https://github.com/dotnet/fsharp/pull/16900))
* Completion: fix completion in empty dot lambda prefix ([#16829](https://github.com/dotnet/fsharp/pull/16829))
* Fix StackOverflow when checking non-recursive bindings in module or namespace in `fscAnyCpu`/`fsiAnyCpu`. ([PR #16908](https://github.com/dotnet/fsharp/pull/16908))

Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10086,7 +10086,6 @@ and TcMethodApplication
// Handle post-hoc property assignments
let setterExprPrebinders, callExpr2b =
let expr = callExpr2

CheckRequiredProperties g env cenv finalCalledMethInfo finalAssignedItemSetters mMethExpr

if isCheckingAttributeCall then
Expand Down Expand Up @@ -10161,6 +10160,8 @@ and TcSetterArgExpr (cenv: cenv) env denv objExpr ad assignedSetter calledFromCo
match setter with
| AssignedPropSetter (propStaticTyOpt, pinfo, pminfo, pminst) ->

CheckPropInfoAttributes pinfo id.idRange |> CommitOperationResult

if g.langVersion.SupportsFeature(LanguageFeature.RequiredPropertiesSupport) && pinfo.IsSetterInitOnly && not calledFromConstructor then
errorR (Error (FSComp.SR.tcInitOnlyPropertyCannotBeSet1 pinfo.PropertyName, m))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace Language

open FSharp.Test
open Xunit
open FSharp.Test.Compiler

Expand Down Expand Up @@ -1262,3 +1263,185 @@ let f (x: IFirst) = x.F()
(Error 101, Line 13, Col 11, Line 13, Col 17, "This construct is deprecated. Use G instead")
(Error 72, Line 13, Col 21, Line 13, Col 24, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.")
]

[<Fact>]
let ``Obsolete attribute warning is taken into account in a constructor property assignment`` () =
Fsx """
open System
type JsonSerializerOptions() =
[<Obsolete("This is bad")>]
member val DefaultOptions = false with get, set

member val UseCustomOptions = false with get, set

let options = JsonSerializerOptions(DefaultOptions = true, UseCustomOptions = false)
let options2 = JsonSerializerOptions(DefaultOptions = true, DefaultOptions = false)
"""
|> typecheck
|> shouldFail
|> withDiagnostics [
(Warning 44, Line 9, Col 37, Line 9, Col 51, "This construct is deprecated. This is bad")
(Error 364, Line 10, Col 16, Line 10, Col 84, "The named argument 'DefaultOptions' has been assigned more than one value")
(Warning 44, Line 10, Col 38, Line 10, Col 52, "This construct is deprecated. This is bad")
(Warning 44, Line 10, Col 61, Line 10, Col 75, "This construct is deprecated. This is bad")
]

[<Fact>]
let ``Obsolete attribute warning is not taken into account in prop setters that can be included in methods which are not constructors`` () =
Fsx """
open System

type JsonSerializerOptions() =
[<Obsolete("This is bad")>]
member val DefaultOptions = false with get, set
member val UseCustomOptions = false with get, set
member this.With() = this

let options = JsonSerializerOptions()
let options2 =
options
.With(DefaultOptions = true)
.With(UseCustomOptions = false)
"""
|> typecheck
|> withDiagnostics [
(Warning 44, Line 13, Col 15, Line 13, Col 29, "This construct is deprecated. This is bad")
]

[<Fact>]
let ``Obsolete attribute error is not taken into account in prop setters that can be included in methods which are not constructors`` () =
Fsx """
open System

type JsonSerializerOptions() =
[<Obsolete("This is bad", true)>]
member val DefaultOptions = false with get, set
member val UseCustomOptions = false with get, set
member this.With() = this

let options = JsonSerializerOptions()
let options2 =
options
.With(DefaultOptions = true)
.With(UseCustomOptions = false)
"""
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 101, Line 13, Col 15, Line 13, Col 29, "This construct is deprecated. This is bad")
]

[<Fact>]
let ``Obsolete attribute error is taken into account in a constructor property assignment`` () =
Fsx """
open System
type JsonSerializerOptions() =
[<Obsolete("This is bad", true)>]
member val DefaultOptions = false with get, set

member val UseCustomOptions = false with get, set

let options = JsonSerializerOptions(DefaultOptions = true, UseCustomOptions = false)
let options2 = JsonSerializerOptions(DefaultOptions = true, DefaultOptions = false)
"""
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 101, Line 9, Col 37, Line 9, Col 51, "This construct is deprecated. This is bad");
(Error 364, Line 10, Col 16, Line 10, Col 84, "The named argument 'DefaultOptions' has been assigned more than one value");
(Error 101, Line 10, Col 38, Line 10, Col 52, "This construct is deprecated. This is bad")
]

[<Fact>]
let ``Obsolete attribute warning is taken into account in a nested constructor property assignment`` () =
Fsx """
open System
type JsonSerializer1Options() =
[<Obsolete("This is bad")>]
member val DefaultOptions = false with get, set

member val UseCustomOptions = false with get, set

type JsonSerializerOptions() =
member val DefaultOptions = JsonSerializer1Options() with get, set

member val UseCustomOptions = false with get, set

let options = JsonSerializerOptions(DefaultOptions = JsonSerializer1Options(DefaultOptions = true), UseCustomOptions = false)
"""
|> typecheck
|> shouldFail
|> withDiagnostics [
(Warning 44, Line 14, Col 77, Line 14, Col 91, "This construct is deprecated. This is bad")
]

[<Fact>]
let ``Obsolete attribute error is taken into account in a nested constructor property assignment`` () =
Fsx """
open System
type JsonSerializer1Options() =
[<Obsolete("This is bad", true)>]
member val DefaultOptions = false with get, set

member val UseCustomOptions = false with get, set

type JsonSerializerOptions() =
member val DefaultOptions = JsonSerializer1Options() with get, set

member val UseCustomOptions = false with get, set

let options = JsonSerializerOptions(DefaultOptions = JsonSerializer1Options(DefaultOptions = true), UseCustomOptions = false)
"""
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 101, Line 14, Col 77, Line 14, Col 91, "This construct is deprecated. This is bad")
]

[<Fact>]
let ``Obsolete attribute warning is taken into account in a constructor property assignment from a csharp class`` () =
let CSLib =
CSharp """
using System;
public class JsonProtocolTestData {
[Obsolete("Use Json instead")]
public bool IgnoreNullValues { get; set; }
}
""" |> withName "CSLib"

let app =
FSharp """
module ObsoleteStruct.FS
let res = JsonProtocolTestData(IgnoreNullValues = false)
""" |> withReferences [CSLib]

app
|> compile
|> shouldFail
|> withDiagnostics [
(Warning 44, Line 3, Col 32, Line 3, Col 48, "This construct is deprecated. Use Json instead")
]

[<Fact>]
let ``Obsolete attribute error is taken into account in a constructor property assignment from a csharp class`` () =
let CSLib =
CSharp """
using System;
public class JsonProtocolTestData {
[Obsolete("Use Json instead", true)]
public bool IgnoreNullValues { get; set; }
}
""" |> withName "CSLib"

let app =
FSharp """
module ObsoleteStruct.FS
let res = JsonProtocolTestData(IgnoreNullValues = false)
""" |> withReferences [CSLib]

app
|> compile
|> shouldFail
|> withDiagnostics [
(Error 101, Line 3, Col 32, Line 3, Col 48, "This construct is deprecated. Use Json instead")
]