Skip to content

Commit 7884d62

Browse files
authored
Warning when using instance properties on static classes (#14639)
* Warning when uisng member properties on static classes * Use Warning intead of Error as agreed
1 parent 382d766 commit 7884d62

File tree

2 files changed

+63
-30
lines changed

2 files changed

+63
-30
lines changed

src/Compiler/Checking/CheckDeclarations.fs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,19 +1670,22 @@ let private ReportErrorOnStaticClass (synMembers: SynMemberDefn list) =
16701670
match mem with
16711671
| SynMemberDefn.ImplicitCtor(ctorArgs = SynSimplePats.SimplePats(pats = pats)) when (not pats.IsEmpty) ->
16721672
for pat in pats do
1673-
errorR(Error(FSComp.SR.chkConstructorWithArgumentsOnStaticClasses(), pat.Range))
1674-
1673+
warning(Error(FSComp.SR.chkConstructorWithArgumentsOnStaticClasses(), pat.Range))
16751674
| SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Constructor ->
1676-
errorR(Error(FSComp.SR.chkAdditionalConstructorOnStaticClasses(), m))
1677-
| SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Member && memberFlags.IsInstance ->
1678-
errorR(Error(FSComp.SR.chkInstanceMemberOnStaticClasses(), m))
1675+
warning(Error(FSComp.SR.chkAdditionalConstructorOnStaticClasses(), m))
1676+
| SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.IsInstance ->
1677+
match memberFlags.MemberKind with
1678+
| SynMemberKind.PropertyGet | SynMemberKind.PropertySet | SynMemberKind.PropertyGetSet
1679+
| SynMemberKind.Member ->
1680+
warning(Error(FSComp.SR.chkInstanceMemberOnStaticClasses(), m))
1681+
| _ -> ()
16791682
| SynMemberDefn.LetBindings(isStatic = false; range = range) ->
1680-
errorR(Error(FSComp.SR.chkInstanceLetBindingOnStaticClasses(), range))
1683+
warning(Error(FSComp.SR.chkInstanceLetBindingOnStaticClasses(), range))
16811684
| SynMemberDefn.Interface(members= Some(synMemberDefs)) ->
16821685
for mem in synMemberDefs do
16831686
match mem with
16841687
| SynMemberDefn.Member(SynBinding(valData = SynValData(memberFlags = Some memberFlags)), m) when memberFlags.MemberKind = SynMemberKind.Member && memberFlags.IsInstance ->
1685-
errorR(Error(FSComp.SR.chkImplementingInterfacesOnStaticClasses(), m))
1688+
warning(Error(FSComp.SR.chkImplementingInterfacesOnStaticClasses(), m))
16861689
| _ -> ()
16871690
| _ -> ()
16881691

@@ -1795,11 +1798,11 @@ let TcMutRecDefns_Phase2 (cenv: cenv) envInitial mBinds scopem mutRecNSInfo (env
17951798
match tyconOpt with
17961799
| Some tycon ->
17971800
for slot in tycon.FSharpObjectModelTypeInfo.fsobjmodel_vslots do
1798-
errorR(Error(FSComp.SR.chkAbstractMembersDeclarationsOnStaticClasses(), slot.Range))
1801+
warning(Error(FSComp.SR.chkAbstractMembersDeclarationsOnStaticClasses(), slot.Range))
17991802

18001803
for fld in tycon.AllFieldsArray do
18011804
if not fld.IsStatic then
1802-
errorR(Error(FSComp.SR.chkExplicitFieldsDeclarationsOnStaticClasses(), fld.Range))
1805+
warning(Error(FSComp.SR.chkExplicitFieldsDeclarationsOnStaticClasses(), fld.Range))
18031806
| None -> ()
18041807

18051808
let envForDecls =

tests/FSharp.Compiler.ComponentTests/Language/StaticClassTests.fs

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ type T(x: int) = class end
5555
|> compile
5656
|> shouldFail
5757
|> withDiagnostics [
58-
(Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed.")
58+
(Warning 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed.")
5959
]
6060

6161
[<Fact>]
@@ -79,7 +79,7 @@ type T =
7979
|> compile
8080
|> shouldFail
8181
|> withDiagnostics [
82-
(Error 3553, Line 4, Col 5, Line 4, Col 16, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed.")
82+
(Warning 3553, Line 4, Col 5, Line 4, Col 16, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed.")
8383
]
8484

8585
[<Fact>]
@@ -104,8 +104,8 @@ type T(x: int) =
104104
|> compile
105105
|> shouldFail
106106
|> withDiagnostics [
107-
(Error 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed.")
108-
(Error 3553, Line 4, Col 5, Line 4, Col 19, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed.")
107+
(Warning 3552, Line 3, Col 8, Line 3, Col 14, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed.")
108+
(Warning 3553, Line 4, Col 5, Line 4, Col 19, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed.")
109109
]
110110

111111
[<Fact>]
@@ -140,7 +140,7 @@ type ListDebugView<'T>(l: 'T list) = class end
140140
|> compile
141141
|> shouldFail
142142
|> withDiagnostics [
143-
(Error 3552, Line 3, Col 24, Line 3, Col 34, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed.")
143+
(Warning 3552, Line 3, Col 24, Line 3, Col 34, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Constructor with arguments is not allowed.")
144144
]
145145

146146
[<Fact>]
@@ -156,9 +156,9 @@ type B =
156156
|> compile
157157
|> shouldFail
158158
|> withDiagnostics [
159-
(Error 3553, Line 6, Col 5, Line 6, Col 30, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed.")
160-
(Error 3558, Line 4, Col 9, Line 4, Col 10, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
161-
(Error 3558, Line 5, Col 17, Line 5, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
159+
(Warning 3553, Line 6, Col 5, Line 6, Col 30, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Additional constructor is not allowed.")
160+
(Warning 3558, Line 4, Col 9, Line 4, Col 10, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
161+
(Warning 3558, Line 5, Col 17, Line 5, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
162162
]
163163

164164
[<Theory>]
@@ -229,7 +229,7 @@ type T() =
229229
|> compile
230230
|> shouldFail
231231
|> withDiagnostics [
232-
(Error 3554, Line 4, Col 5, Line 4, Col 25, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance members are not allowed.")
232+
(Warning 3554, Line 4, Col 5, Line 4, Col 25, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance members are not allowed.")
233233
]
234234

235235
[<Fact>]
@@ -316,7 +316,7 @@ type C() =
316316
|> compile
317317
|> shouldFail
318318
|> withDiagnostics [
319-
(Error 3555, Line 4, Col 5, Line 4, Col 14, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance let bindings are not allowed.")
319+
(Warning 3555, Line 4, Col 5, Line 4, Col 14, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance let bindings are not allowed.")
320320
]
321321

322322
[<Fact>]
@@ -331,7 +331,7 @@ type C() =
331331
|> compile
332332
|> shouldFail
333333
|> withDiagnostics [
334-
(Error 3555, Line 4, Col 5, Line 4, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance let bindings are not allowed.")
334+
(Warning 3555, Line 4, Col 5, Line 4, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance let bindings are not allowed.")
335335
]
336336

337337
[<Fact>]
@@ -403,7 +403,7 @@ type C() =
403403
|> compile
404404
|> shouldFail
405405
|> withDiagnostics [
406-
(Error 3556, Line 8, Col 9, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
406+
(Warning 3556, Line 8, Col 9, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
407407
]
408408

409409
[<Fact>]
@@ -421,7 +421,7 @@ type C =
421421
|> compile
422422
|> shouldFail
423423
|> withDiagnostics [
424-
(Error 3556, Line 8, Col 9, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
424+
(Warning 3556, Line 8, Col 9, Line 8, Col 29, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Implementing interfaces is not allowed.")
425425
]
426426

427427
[<Fact>]
@@ -464,8 +464,8 @@ type T =
464464
|> compile
465465
|> shouldFail
466466
|> withDiagnostics [
467-
(Error 3557, Line 4, Col 14, Line 4, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
468-
(Error 3557, Line 5, Col 14, Line 5, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
467+
(Warning 3557, Line 4, Col 14, Line 4, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
468+
(Warning 3557, Line 5, Col 14, Line 5, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
469469
]
470470

471471
[<Fact>]
@@ -480,8 +480,8 @@ type T() =
480480
|> compile
481481
|> shouldFail
482482
|> withDiagnostics [
483-
(Error 3557, Line 4, Col 14, Line 4, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
484-
(Error 3557, Line 5, Col 14, Line 5, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
483+
(Warning 3557, Line 4, Col 14, Line 4, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
484+
(Warning 3557, Line 5, Col 14, Line 5, Col 15, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Abstract member declarations are not allowed.")
485485
]
486486

487487
#if !NETCOREAPP
@@ -665,8 +665,8 @@ type B =
665665
|> compile
666666
|> shouldFail
667667
|> withDiagnostics [
668-
(Error 3558, Line 4, Col 9, Line 4, Col 10, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
669-
(Error 3558, Line 5, Col 17, Line 5, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
668+
(Warning 3558, Line 4, Col 9, Line 4, Col 10, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
669+
(Warning 3558, Line 5, Col 17, Line 5, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
670670
]
671671

672672
[<Fact>]
@@ -683,7 +683,37 @@ type B() =
683683
|> withDiagnostics [
684684
(Error 880, Line 4, Col 9, Line 4, Col 16, "Uninitialized 'val' fields must be mutable and marked with the '[<DefaultValue>]' attribute. Consider using a 'let' binding instead of a 'val' field.")
685685
(Error 880, Line 5, Col 17, Line 5, Col 24, "Uninitialized 'val' fields must be mutable and marked with the '[<DefaultValue>]' attribute. Consider using a 'let' binding instead of a 'val' field.")
686-
(Error 3558, Line 4, Col 9, Line 4, Col 10, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
687-
(Error 3558, Line 5, Col 17, Line 5, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
686+
(Warning 3558, Line 4, Col 9, Line 4, Col 10, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
687+
(Warning 3558, Line 5, Col 17, Line 5, Col 18, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Explicit field declarations are not allowed.")
688688
]
689+
690+
[<Fact>]
691+
let ``Sealed and AbstractClass on a types with instance member properties on lang version70`` () =
692+
Fsx """
693+
[<Sealed; AbstractClass>]
694+
type T =
695+
member _.Item with get i = 3
696+
member _.Item1 with set i value = ()
697+
member _.Item2 with get i = 3 and set i value = ()
698+
"""
699+
|> withLangVersion70
700+
|> compile
701+
|> shouldSucceed
689702

703+
[<Fact>]
704+
let ``Sealed and AbstractClass on a types with instance member properties on lang preview`` () =
705+
Fsx """
706+
[<Sealed; AbstractClass>]
707+
type T =
708+
member _.Item with get i = 3
709+
member _.Item1 with set i value = ()
710+
member _.Item2 with get i = 3 and set i value = ()
711+
"""
712+
|> withLangVersionPreview
713+
|> compile
714+
|> shouldFail
715+
|> withDiagnostics [
716+
(Warning 3554, Line 4, Col 5, Line 4, Col 33, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance members are not allowed.")
717+
(Warning 3554, Line 5, Col 5, Line 5, Col 41, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance members are not allowed.")
718+
(Warning 3554, Line 6, Col 5, Line 6, Col 55, "If a type uses both [<Sealed>] and [<AbstractClass>] attributes, it means it is static. Instance members are not allowed.")
719+
]

0 commit comments

Comments
 (0)