Skip to content
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

Error message that explicitly disallows static abstract members in classes. #17055

Merged
merged 6 commits into from
Apr 17, 2024
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.400.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Fixed

* Static abstract method on classes no longer yields internal error. ([Issue #17044](https://github.com/dotnet/fsharp/issues/17044), [PR #17055](https://github.com/dotnet/fsharp/pull/17055))
* Disallow calling abstract methods directly on interfaces. ([Issue #14012](https://github.com/dotnet/fsharp/issues/14012), [Issue #16299](https://github.com/dotnet/fsharp/issues/16299), [PR #17021](https://github.com/dotnet/fsharp/pull/17021))
* Various parenthesization API fixes. ([PR #16977](https://github.com/dotnet/fsharp/pull/16977))
* Fix bug in optimization of for-loops over integral ranges with steps and units of measure. ([Issue #17025](https://github.com/dotnet/fsharp/issues/17025), [PR #17040](https://github.com/dotnet/fsharp/pull/17040), [PR #17048](https://github.com/dotnet/fsharp/pull/17048))
Expand Down
35 changes: 19 additions & 16 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3608,6 +3608,20 @@ module EstablishTypeDefinitionCores =
elif not (isClassTy g ty) then
errorR(Error(FSComp.SR.tcCannotInheritFromInterfaceType(), m)))

let abstractSlots =
[ for synValSig, memberFlags in slotsigs do

let (SynValSig(range=m)) = synValSig

CheckMemberFlags None NewSlotsOK OverridesOK memberFlags m

let slots = fst (TcAndPublishValSpec (cenv, envinner, containerInfo, ModuleOrMemberBinding, Some memberFlags, tpenv, synValSig))
// Multiple slots may be returned, e.g. for
// abstract P: int with get, set

for slot in slots do
yield mkLocalValRef slot ]

let kind =
match kind with
| SynTypeDefnKind.Struct ->
Expand All @@ -3632,6 +3646,9 @@ module EstablishTypeDefinitionCores =
noCLIMutableAttributeCheck()
structLayoutAttributeCheck(not isIncrClass)
allowNullLiteralAttributeCheck()
for slot in abstractSlots do
if not slot.IsInstanceMember then
errorR(Error(FSComp.SR.chkStaticAbstractMembersOnClasses(), slot.Range))
TFSharpClass
| SynTypeDefnKind.Delegate (ty, arity) ->
noCLIMutableAttributeCheck()
Expand Down Expand Up @@ -3666,21 +3683,7 @@ module EstablishTypeDefinitionCores =
| (_, m, baseIdOpt) :: _ ->
match baseIdOpt with
| None -> Some(ident("base", m))
| Some id -> Some id

let abstractSlots =
[ for synValSig, memberFlags in slotsigs do

let (SynValSig(range=m)) = synValSig

CheckMemberFlags None NewSlotsOK OverridesOK memberFlags m

let slots = fst (TcAndPublishValSpec (cenv, envinner, containerInfo, ModuleOrMemberBinding, Some memberFlags, tpenv, synValSig))
// Multiple slots may be returned, e.g. for
// abstract P: int with get, set

for slot in slots do
yield mkLocalValRef slot ]
| Some id -> Some id

let baseValOpt = MakeAndPublishBaseVal cenv envinner baseIdOpt (superOfTycon g tycon)
let safeInitInfo = ComputeInstanceSafeInitInfo cenv envinner thisTyconRef.Range thisTy
Expand Down Expand Up @@ -4453,7 +4456,7 @@ module TcDeclarations =

let slotsigs = members |> List.choose (function SynMemberDefn.AbstractSlot (slotSig = x; flags = y) -> Some(x, y) | _ -> None)

let members,_vals_Inherits_Abstractslots = SplitAutoProps members
let members, _vals_Inherits_Abstractslots = SplitAutoProps members

let isConcrete =
members |> List.exists (function
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1746,4 +1746,5 @@ featureReuseSameFieldsInStructUnions,"Share underlying fields in a [<Struct>] di
3863,parsExpectingField,"Expecting record field"
3864,tooManyMethodsInDotNetTypeWritingAssembly,"The type '%s' has too many methods. Found: '%d', maximum: '%d'"
3865,parsOnlySimplePatternsAreAllowedInConstructors,"Only simple patterns are allowed in primary constructors"
3866,chkStaticAbstractInterfaceMembers,"A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.%s)."
3866,chkStaticAbstractInterfaceMembers,"A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.%s)."
3867,chkStaticAbstractMembersOnClasses,"Classes cannot contain static abstract members."
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hans.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hant.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1241,4 +1241,31 @@ printf "%A" res"""
(Error 3866, Line 12, Col 82, Line 12, Col 126, "A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.op_Addition).")
(Error 3866, Line 13, Col 82, Line 13, Col 126, "A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.op_Addition).")
(Error 3866, Line 15, Col 82, Line 15, Col 129, "A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.Parse).")
]
]

[<FactForNETCOREAPP>]
let ``Error message that explicitly disallows static abstract methods in abstract classes.`` () =
Fsx """
[<AbstractClass>]
type A () =
static abstract M : unit -> unit
"""
|> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ]
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 3867, Line 4, Col 21, Line 4, Col 22, "Classes cannot contain static abstract members.")
]

[<FactForNETCOREAPP>]
let ``Error message that explicitly disallows static abstract methods in classes.`` () =
Fsx """
type A () =
static abstract M : unit -> unit
"""
|> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ]
|> typecheck
|> shouldFail
|> withDiagnostics [
(Error 3867, Line 3, Col 21, Line 3, Col 22, "Classes cannot contain static abstract members.")
]
Loading