From 79df557b009bfab871e3c3bcb29c751a67c4707a Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 10 Apr 2024 19:27:52 +0100 Subject: [PATCH 01/12] Disallow calling abstract methods directly on interfaces --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + src/Compiler/Checking/ConstraintSolver.fs | 12 +++++-- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 32 ++++++++++++++++++- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 57bc1578db3..3ff7b03658a 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -1,5 +1,6 @@ ### Fixed +* Disallow calling abstract methods directly on interfaces. ([PR #16319](https://github.com/dotnet/fsharp/pull/16319)) * Fix a false positive of the `[]` analysis in combination with `yield!`. ([PR #16933](https://github.com/dotnet/fsharp/pull/16933)) * Improve error reporting: ambiguous override method in object expression. ([PR #16985](https://github.com/dotnet/fsharp/pull/16985)) * Don't blow the stack when traversing deeply nested sequential expressions. ([PR #16882](https://github.com/dotnet/fsharp/pull/16882)) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 2667ea6ccfc..38c7250b887 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -2942,10 +2942,16 @@ and ResolveOverloading let candidates = calledMethGroup |> List.filter (fun cmeth -> cmeth.IsCandidate(m, ad)) let calledMethOpt, errors, calledMethTrace = - match calledMethGroup, candidates with - | _, [calledMeth] when not isOpConversion -> - Some calledMeth, CompleteD, NoTrace + | _, [calledMeth] when not isOpConversion -> + // See what candidates we have based on static/virtual/abstract + // OK: static virtual TResult operator checked i.e. IAdditionOperators.op_CheckedAddition + // Error: static abstract TResult operator i.e. IAdditionOperators.op_Addition + match calledMeth.Method with + | ILMeth(ilMethInfo= ilMethInfo) when ilMethInfo.IsStatic && ilMethInfo.IsVirtual && methodName.Contains("op_") && ilMethInfo.IsAbstract -> + // Do don't want to make available via completion, as it will lead to the compile time error. I.e. not usable if it's non-virtual + None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace + | _ -> Some calledMeth, CompleteD, NoTrace | [], _ when not isOpConversion -> None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index d3d7be2cf36..56aea79ca30 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1183,4 +1183,34 @@ let execute = IPrintable.Say("hello") |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] |> withLangVersion80 |> typecheck - |> shouldSucceed \ No newline at end of file + |> shouldSucceed + + + [] + let ``Accessing to IWSAM(System.Numerics non virtual) produces a compilation error`` () = + Fsx """ +open System.Numerics + +IAdditionOperators.op_Addition (3, 6) + """ + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> withLangVersion80 + |> compile + |> shouldFail + |> withSingleDiagnostic (Error 509, Line 4, Col 1, Line 4, Col 38, "Method or object constructor 'op_Addition' not found") + + [] + let ``Accessing to IWSAM(System.Numerics virtual member) compiles and runs`` () = + Fsx """ +open System.Numerics + +let res = IAdditionOperators.op_CheckedAddition (3, 6) + +printf "%A" res""" + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> withLangVersion80 + |> asExe + |> compile + |> shouldSucceed + |> run + |> verifyOutput "9" \ No newline at end of file From d8d9062e26f602de0926e09d4f278d5486432724 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 11 Apr 2024 16:36:57 +0100 Subject: [PATCH 02/12] More tests --- .../ConstrainedAndInterfaceCalls.fs | 29 +++++++++++++++++++ .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 28 +++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs new file mode 100644 index 00000000000..e80ec416701 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs @@ -0,0 +1,29 @@ +#nowarn "64" +open System +open System.Numerics + +module ConstrainedCall = + let ``'T.op_Addition``<'T & #IAdditionOperators<'T, 'T, 'T>> x y = 'T.op_Addition (x, y) + let ``'T.(+)``<'T & #IAdditionOperators<'T, 'T, 'T>> x y = 'T.(+) (x, y) + let ``'T.op_CheckedAddition``<'T & #IAdditionOperators<'T, 'T, 'T>> x y = 'T.op_CheckedAddition (x, y) + let ``'T.Parse``<'T & #IParsable<'T>> x = 'T.Parse (x, null) + +module InterfaceCall = + let ``IAdditionOperators.op_Addition`` x y = IAdditionOperators.op_Addition (x, y) + let ``IAdditionOperators.(+)`` x y = IAdditionOperators.(+) (x, y) + let ``IAdditionOperators.op_CheckedAddition`` x y = IAdditionOperators.op_CheckedAddition (x, y) + let ``IParsable.Parse``<'T & #IParsable<'T>> x : 'T = IParsable.Parse (x, null) + +open ConstrainedCall + +printfn $"{``'T.op_Addition`` 1 2}" // Prints 3. +printfn $"{``'T.(+)`` 1 2}" // Prints 3. +printfn $"{``'T.op_CheckedAddition`` 1 2}" // Prints 3. +printfn $"""{``'T.Parse`` "3"}""" // Prints 3. + +open InterfaceCall + +printfn $"{``IAdditionOperators.op_Addition`` 1 2}" // System.BadImageFormatException: Bad IL format. +printfn $"{``IAdditionOperators.(+)`` 1 2}" // System.BadImageFormatException: Bad IL format. +printfn $"{``IAdditionOperators.op_CheckedAddition`` 1 2}" // Prints 3. +printfn $"""{``IParsable.Parse`` "3"}""" // System.BadImageFormatException: Bad IL format. diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 56aea79ca30..ed5cbb65761 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -19,6 +19,18 @@ module TypesAndTypeConstraints_IWSAMsAndSRTPs = |> asExe |> withLangVersion70 |> withReferences [typesModule] + + let verifyCompile compilation = + compilation + |> asExe + |> withOptions ["--nowarn:988"] + |> compile + + let verifyCompileAndRun compilation = + compilation + |> asExe + |> withOptions ["--nowarn:988"] + |> compileAndRun [] let ``Srtp call Zero property returns valid result`` () = @@ -1213,4 +1225,18 @@ printf "%A" res""" |> compile |> shouldSucceed |> run - |> verifyOutput "9" \ No newline at end of file + |> verifyOutput "9" + + // SOURCE=ConstrainedAndInterfaceCalls.fs # AssemblyVersion01.fs + [] + let ``ConstrainedAndInterfaceCalls.fs`` compilation = + compilation + |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] + |> verifyCompile + |> shouldFail + |> withDiagnostics [ + (Error 509, Line 6, Col 82, Line 6, Col 110, "Method or object constructor 'op_Addition' not found") + (Error 509, Line 7, Col 82, Line 7, Col 110, "Method or object constructor 'op_Addition' not found") + (Error 509, Line 12, Col 82, Line 12, Col 126, "Method or object constructor 'op_Addition' not found") + (Error 509, Line 13, Col 82, Line 13, Col 126, "Method or object constructor 'op_Addition' not found") + ] \ No newline at end of file From b5427091122e306ed4bd0ab5f38601496208fc42 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 11 Apr 2024 17:47:31 +0100 Subject: [PATCH 03/12] IWSAMs are not supported by NET472 --- .../TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index ed5cbb65761..88f533291e7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1226,9 +1226,13 @@ printf "%A" res""" |> shouldSucceed |> run |> verifyOutput "9" - + +#if !NETCOREAPP + [] +#else // SOURCE=ConstrainedAndInterfaceCalls.fs # AssemblyVersion01.fs [] +#endif let ``ConstrainedAndInterfaceCalls.fs`` compilation = compilation |> withOptions [ "--nowarn:3536" ; "--nowarn:3535" ] From 7fa7b8f5fb11fce1b49e213281217a1bfb3b63f4 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Thu, 11 Apr 2024 20:09:18 +0100 Subject: [PATCH 04/12] Update src/Compiler/Checking/ConstraintSolver.fs Co-authored-by: Tomas Grosup --- src/Compiler/Checking/ConstraintSolver.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 38c7250b887..b72c917b3e0 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -2948,7 +2948,7 @@ and ResolveOverloading // OK: static virtual TResult operator checked i.e. IAdditionOperators.op_CheckedAddition // Error: static abstract TResult operator i.e. IAdditionOperators.op_Addition match calledMeth.Method with - | ILMeth(ilMethInfo= ilMethInfo) when ilMethInfo.IsStatic && ilMethInfo.IsVirtual && methodName.Contains("op_") && ilMethInfo.IsAbstract -> + | ILMeth(ilMethInfo= ilMethInfo) when ilMethInfo.IsStatic && ilMethInfo.IsVirtual && ilMethInfo.IsAbstract -> // Do don't want to make available via completion, as it will lead to the compile time error. I.e. not usable if it's non-virtual None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace | _ -> Some calledMeth, CompleteD, NoTrace From 7fa370b6a5581063faf6ca95bca13ba8cc905b6c Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 12 Apr 2024 21:47:06 +0100 Subject: [PATCH 05/12] fix typos --- src/Compiler/Checking/ConstraintSolver.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index b72c917b3e0..b890f25f76a 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -2945,11 +2945,11 @@ and ResolveOverloading match calledMethGroup, candidates with | _, [calledMeth] when not isOpConversion -> // See what candidates we have based on static/virtual/abstract - // OK: static virtual TResult operator checked i.e. IAdditionOperators.op_CheckedAddition - // Error: static abstract TResult operator i.e. IAdditionOperators.op_Addition + // OK: static virtual TResult operator checked e.g. IAdditionOperators.op_CheckedAddition + // Error: static abstract TResult operator e.g. IAdditionOperators.op_Addition match calledMeth.Method with - | ILMeth(ilMethInfo= ilMethInfo) when ilMethInfo.IsStatic && ilMethInfo.IsVirtual && ilMethInfo.IsAbstract -> - // Do don't want to make available via completion, as it will lead to the compile time error. I.e. not usable if it's non-virtual + | ILMeth(ilMethInfo= ilMethInfo) when ilMethInfo.IsStatic && ilMethInfo.IsAbstract -> + // Don't want to make available via completion, as it will lead to the compile time error. I.e. not usable if it's non-virtual None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace | _ -> Some calledMeth, CompleteD, NoTrace From ce7acc2acdc6a7ef50d05739a462c2f0fe3f361b Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Sun, 14 Apr 2024 21:40:53 +0100 Subject: [PATCH 06/12] looking for the right check --- src/Compiler/Checking/ConstraintSolver.fs | 9 +++++++-- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 4 +--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index b890f25f76a..530b9655bb9 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -2947,9 +2947,14 @@ and ResolveOverloading // See what candidates we have based on static/virtual/abstract // OK: static virtual TResult operator checked e.g. IAdditionOperators.op_CheckedAddition // Error: static abstract TResult operator e.g. IAdditionOperators.op_Addition + let isConstrainedCall = + match calledMeth.OptionalStaticType with + | Some ttype -> isTyparTy g ttype + | None -> false + match calledMeth.Method with - | ILMeth(ilMethInfo= ilMethInfo) when ilMethInfo.IsStatic && ilMethInfo.IsAbstract -> - // Don't want to make available via completion, as it will lead to the compile time error. I.e. not usable if it's non-virtual + | ILMeth(ilMethInfo= ilMethInfo) when not isConstrainedCall && ilMethInfo.IsStatic && ilMethInfo.IsAbstract -> + // Don't want to make available via completion, as it will lead to the compile time error e.g. not usable if it's non-virtual None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace | _ -> Some calledMeth, CompleteD, NoTrace diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 88f533291e7..ffd71831b01 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1196,7 +1196,6 @@ let execute = IPrintable.Say("hello") |> withLangVersion80 |> typecheck |> shouldSucceed - [] let ``Accessing to IWSAM(System.Numerics non virtual) produces a compilation error`` () = @@ -1239,8 +1238,7 @@ printf "%A" res""" |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 509, Line 6, Col 82, Line 6, Col 110, "Method or object constructor 'op_Addition' not found") - (Error 509, Line 7, Col 82, Line 7, Col 110, "Method or object constructor 'op_Addition' not found") (Error 509, Line 12, Col 82, Line 12, Col 126, "Method or object constructor 'op_Addition' not found") (Error 509, Line 13, Col 82, Line 13, Col 126, "Method or object constructor 'op_Addition' not found") + (Error 509, Line 15, Col 82, Line 15, Col 129, "Method or object constructor 'Parse' not found") ] \ No newline at end of file From 1fc2c7323af25701a3695658b2201c6834054336 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 15 Apr 2024 10:18:04 +0100 Subject: [PATCH 07/12] Add comments --- src/Compiler/Checking/ConstraintSolver.fs | 11 +++++++---- .../IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs | 13 ------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 530b9655bb9..4910cb315a5 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -2945,15 +2945,18 @@ and ResolveOverloading match calledMethGroup, candidates with | _, [calledMeth] when not isOpConversion -> // See what candidates we have based on static/virtual/abstract - // OK: static virtual TResult operator checked e.g. IAdditionOperators.op_CheckedAddition - // Error: static abstract TResult operator e.g. IAdditionOperators.op_Addition - let isConstrainedCall = + + // If false then is a static method call directly on an interface e.g. + // IParsable.Parse(...) + // IAdditionOperators.(+) + // This is not allowed as Parse and (+) method are static abstract + let isStaticConstrainedCall = match calledMeth.OptionalStaticType with | Some ttype -> isTyparTy g ttype | None -> false match calledMeth.Method with - | ILMeth(ilMethInfo= ilMethInfo) when not isConstrainedCall && ilMethInfo.IsStatic && ilMethInfo.IsAbstract -> + | ILMeth(ilMethInfo= ilMethInfo) when not isStaticConstrainedCall && ilMethInfo.IsStatic && ilMethInfo.IsAbstract -> // Don't want to make available via completion, as it will lead to the compile time error e.g. not usable if it's non-virtual None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace | _ -> Some calledMeth, CompleteD, NoTrace diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs index e80ec416701..740eff41812 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/ConstrainedAndInterfaceCalls.fs @@ -14,16 +14,3 @@ module InterfaceCall = let ``IAdditionOperators.op_CheckedAddition`` x y = IAdditionOperators.op_CheckedAddition (x, y) let ``IParsable.Parse``<'T & #IParsable<'T>> x : 'T = IParsable.Parse (x, null) -open ConstrainedCall - -printfn $"{``'T.op_Addition`` 1 2}" // Prints 3. -printfn $"{``'T.(+)`` 1 2}" // Prints 3. -printfn $"{``'T.op_CheckedAddition`` 1 2}" // Prints 3. -printfn $"""{``'T.Parse`` "3"}""" // Prints 3. - -open InterfaceCall - -printfn $"{``IAdditionOperators.op_Addition`` 1 2}" // System.BadImageFormatException: Bad IL format. -printfn $"{``IAdditionOperators.(+)`` 1 2}" // System.BadImageFormatException: Bad IL format. -printfn $"{``IAdditionOperators.op_CheckedAddition`` 1 2}" // Prints 3. -printfn $"""{``IParsable.Parse`` "3"}""" // System.BadImageFormatException: Bad IL format. From f1310d5dee60725b40578e803eb1db41b40fedfe Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 15 Apr 2024 12:33:10 +0100 Subject: [PATCH 08/12] move release notes --- docs/release-notes/.FSharp.Compiler.Service/8.0.300.md | 1 - docs/release-notes/.FSharp.Compiler.Service/8.0.400.md | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index 3ff7b03658a..57bc1578db3 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -1,6 +1,5 @@ ### Fixed -* Disallow calling abstract methods directly on interfaces. ([PR #16319](https://github.com/dotnet/fsharp/pull/16319)) * Fix a false positive of the `[]` analysis in combination with `yield!`. ([PR #16933](https://github.com/dotnet/fsharp/pull/16933)) * Improve error reporting: ambiguous override method in object expression. ([PR #16985](https://github.com/dotnet/fsharp/pull/16985)) * Don't blow the stack when traversing deeply nested sequential expressions. ([PR #16882](https://github.com/dotnet/fsharp/pull/16882)) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 9ecdf18ee3e..d469c545050 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -1,3 +1,4 @@ ### Fixed -Various parenthesization API fixes. ([PR #16977](https://github.com/dotnet/fsharp/pull/16977)) +* Disallow calling abstract methods directly on interfaces. ([PR #16319](https://github.com/dotnet/fsharp/pull/16319)) +* Various parenthesization API fixes. ([PR #16977](https://github.com/dotnet/fsharp/pull/16977)) From 604ba023b67cd58a29037b57f924879eff5f970c Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 15 Apr 2024 14:04:51 +0100 Subject: [PATCH 09/12] Add a new error number and message --- src/Compiler/Checking/ConstraintSolver.fs | 2 +- src/Compiler/FSComp.txt | 3 ++- src/Compiler/xlf/FSComp.txt.cs.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 +++++ .../TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 8 ++++---- 16 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 4910cb315a5..d744006e234 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -2958,7 +2958,7 @@ and ResolveOverloading match calledMeth.Method with | ILMeth(ilMethInfo= ilMethInfo) when not isStaticConstrainedCall && ilMethInfo.IsStatic && ilMethInfo.IsAbstract -> // Don't want to make available via completion, as it will lead to the compile time error e.g. not usable if it's non-virtual - None, ErrorD (Error (FSComp.SR.csMethodNotFound(methodName), m)), NoTrace + None, ErrorD (Error (FSComp.SR.chkStaticAbstractInterfaceMembers(), m)), NoTrace | _ -> Some calledMeth, CompleteD, NoTrace | [], _ when not isOpConversion -> diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index acb3eecc210..2a3e19ead6e 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1745,4 +1745,5 @@ featureReuseSameFieldsInStructUnions,"Share underlying fields in a [] di 3862,parsStaticMemberImcompleteSyntax,"Incomplete declaration of a static construct. Use 'static let','static do','static member' or 'static val' for declaration." 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" \ No newline at end of file +3865,parsOnlySimplePatternsAreAllowedInConstructors,"Only simple patterns are allowed in primary constructors" +3866,chkStaticAbstractInterfaceMembers,"A static abstract interface member can be accessed only on a type parameter." \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 4a57c5a229d..a08030c02f2 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -122,6 +122,11 @@ Člen nebo funkce „{0}“ má atribut „TailCallAttribute“, ale nepoužívá se koncovým (tail) rekurzivním způsobem. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Objektové výrazy nemohou implementovat rozhraní se statickými abstraktními členy ani deklarovat statické členy. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 3875895aed7..83752caa7e6 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -122,6 +122,11 @@ Der Member oder die Funktion "{0}" weist das Attribut "TailCallAttribute" auf, wird jedoch nicht endrekursiv verwendet. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Objektausdrücke können keine Schnittstellen mit statischen abstrakten Membern implementieren oder statische Member deklarieren. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 229f3781a88..9141b77fd4c 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -122,6 +122,11 @@ El miembro o la función “{0}” tiene el atributo “TailCallAttribute”, pero no se usa de forma de recursión de cola. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Las expresiones de objeto no pueden implementar interfaces con miembros abstractos estáticos ni declarar miembros estáticos. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 5ace1c2dc39..93c8cdf3411 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -122,6 +122,11 @@ Le membre ou la fonction « {0} » possède l'attribut « TailCallAttribute », mais n'est pas utilisé de manière récursive. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Les expressions d’objet ne peuvent pas implémenter des interfaces avec des membres abstraits statiques ou déclarer des membres statiques. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index c5cb0876c15..3ea6f9441c9 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -122,6 +122,11 @@ Il membro o la funzione "{0}" ha l'attributo "TailCallAttribute", ma non è in uso in modo ricorsivo finale. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Le espressioni di oggetto non possono implementare interfacce con membri astratti statici o dichiarare membri statici. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 04b73c10939..54788fc0300 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -122,6 +122,11 @@ メンバーまたは関数 '{0}' には 'TailCallAttribute' 属性がありますが、末尾の再帰的な方法では使用されていません。 + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. オブジェクト式は、静的抽象メンバーを持つインターフェイスを実装したり、静的メンバーを宣言したりすることはできません。 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index afd1f78ca86..fbbacc2af7a 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -122,6 +122,11 @@ 멤버 또는 함수 '{0}'에 'TailCallAttribute' 특성이 있지만 비상 재귀적인 방식으로 사용되고 있지 않습니다. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. 개체 식은 정적 추상 멤버가 있는 인터페이스를 구현하거나 정적 멤버를 선언할 수 없습니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 98611ebcc88..d06f85e224b 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -122,6 +122,11 @@ Składowa lub funkcja „{0}” ma atrybut „TailCallAttribute”, ale nie jest używana w sposób cykliczny końca. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Wyrażenia obiektów nie mogą implementować interfejsów ze statycznymi abstrakcyjnymi elementami członkowskimi ani deklarować statycznych elementów członkowskich. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 9356372d275..84dd2c7b849 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -122,6 +122,11 @@ O membro ou a função "{0}" tem o atributo "TailCallAttribute", mas não está sendo usado de maneira recursiva em cauda. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Expressões de objeto não podem implementar interfaces com membros abstratos estáticos ou declarar membros estáticos. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 6a08c7ada1a..e4ed91f8ef9 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -122,6 +122,11 @@ Элемент или функция "{0}" содержит атрибут "TailCallAttribute", но не используется в рекурсивном хвостовом режиме. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Выражения объектов не могут реализовывать интерфейсы со статическими абстрактными членами или объявлять статические члены. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 7aab43de9c4..54019423467 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -122,6 +122,11 @@ Üye veya '{0}' işlevi, 'TailCallAttribute' özniteliğine sahip ancak kuyruk özyinelemeli bir şekilde kullanılmıyor. + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. Nesne ifadeleri, statik soyut üyeler içeren arabirimleri uygulayamaz veya statik üyeleri bildiremez. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 95715bd1b8a..0b3638e83f5 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -122,6 +122,11 @@ 成员或函数“{0}”具有 "TailCallAttribute" 属性,但未以尾递归方式使用。 + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. 对象表达式无法实现具有静态抽象成员或声明静态成员的接口。 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 5b95c7fe99e..32c115680f4 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -122,6 +122,11 @@ 成員或函式 '{0}' 具有 'TailCallAttribute' 屬性,但未以尾遞迴方式使用。 + + A static abstract interface member can be accessed only on a type parameter. + A static abstract interface member can be accessed only on a type parameter. + + Object expressions cannot implement interfaces with static abstract members or declare static members. 物件運算式無法實作具有靜態抽象成員的介面或宣告靜態成員。 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index ffd71831b01..42b3137064b 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1208,7 +1208,7 @@ IAdditionOperators.op_Addition (3, 6) |> withLangVersion80 |> compile |> shouldFail - |> withSingleDiagnostic (Error 509, Line 4, Col 1, Line 4, Col 38, "Method or object constructor 'op_Addition' not found") + |> withSingleDiagnostic (Error 3866, Line 4, Col 1, Line 4, Col 38, "A static abstract interface member can be accessed only on a type parameter.") [] let ``Accessing to IWSAM(System.Numerics virtual member) compiles and runs`` () = @@ -1238,7 +1238,7 @@ printf "%A" res""" |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 509, Line 12, Col 82, Line 12, Col 126, "Method or object constructor 'op_Addition' not found") - (Error 509, Line 13, Col 82, Line 13, Col 126, "Method or object constructor 'op_Addition' not found") - (Error 509, Line 15, Col 82, Line 15, Col 129, "Method or object constructor 'Parse' not found") + (Error 3866, Line 12, Col 82, Line 12, Col 126, "A static abstract interface member can be accessed only on a type parameter.") + (Error 3866, Line 13, Col 82, Line 13, Col 126, "A static abstract interface member can be accessed only on a type parameter.") + (Error 3866, Line 15, Col 82, Line 15, Col 129, "A static abstract interface member can be accessed only on a type parameter.") ] \ No newline at end of file From df5d20ec303e53451ecae4bf5afcea265d3b9ab7 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 15 Apr 2024 15:44:37 +0100 Subject: [PATCH 10/12] Update docs/release-notes/.FSharp.Compiler.Service/8.0.400.md Co-authored-by: Brian Rourke Boll --- docs/release-notes/.FSharp.Compiler.Service/8.0.400.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 09dcf5c1513..6550bc91b0b 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -1,5 +1,5 @@ ### Fixed -* Disallow calling abstract methods directly on interfaces. ([PR #16319](https://github.com/dotnet/fsharp/pull/16319)) +* Disallow calling abstract methods directly on interfaces. ([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)) From 5154ae879e1e927f354334f0245a12edb0cad4e9 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Mon, 15 Apr 2024 15:48:24 +0100 Subject: [PATCH 11/12] Update docs/release-notes/.FSharp.Compiler.Service/8.0.400.md Co-authored-by: Brian Rourke Boll --- docs/release-notes/.FSharp.Compiler.Service/8.0.400.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 6550bc91b0b..ff20555a305 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -1,5 +1,5 @@ ### Fixed -* Disallow calling abstract methods directly on interfaces. ([PR #17021](https://github.com/dotnet/fsharp/pull/17021)) +* 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)) From 968fe314b0af115b84df301b69fa900d7ba68518 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Tue, 16 Apr 2024 10:20:31 +0100 Subject: [PATCH 12/12] Improve error message --- src/Compiler/Checking/ConstraintSolver.fs | 3 +-- src/Compiler/FSComp.txt | 2 +- src/Compiler/xlf/FSComp.txt.cs.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.de.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.es.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.it.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 4 ++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 4 ++-- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 10 +++++----- 16 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index d744006e234..41c7e26f47e 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -2957,8 +2957,7 @@ and ResolveOverloading match calledMeth.Method with | ILMeth(ilMethInfo= ilMethInfo) when not isStaticConstrainedCall && ilMethInfo.IsStatic && ilMethInfo.IsAbstract -> - // Don't want to make available via completion, as it will lead to the compile time error e.g. not usable if it's non-virtual - None, ErrorD (Error (FSComp.SR.chkStaticAbstractInterfaceMembers(), m)), NoTrace + None, ErrorD (Error (FSComp.SR.chkStaticAbstractInterfaceMembers(ilMethInfo.ILName), m)), NoTrace | _ -> Some calledMeth, CompleteD, NoTrace | [], _ when not isOpConversion -> diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 2a3e19ead6e..e5cabbdc7e3 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1746,4 +1746,4 @@ featureReuseSameFieldsInStructUnions,"Share underlying fields in a [] 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 interface member can be accessed only on a type parameter." \ No newline at end of file +3866,chkStaticAbstractInterfaceMembers,"A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.%s)." \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index a08030c02f2..a7f9808f488 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 83752caa7e6..534e047744f 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 9141b77fd4c..5d2517d1ca9 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 93c8cdf3411..f5c4358314a 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 3ea6f9441c9..350f2decb87 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 54788fc0300..376d3d8d592 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index fbbacc2af7a..f4a42405fcb 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index d06f85e224b..f081661bf4e 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 84dd2c7b849..b17c0b76d24 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index e4ed91f8ef9..7f83d96d646 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 54019423467..f74a800f285 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 0b3638e83f5..19dae40d40a 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 32c115680f4..4f332483292 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -123,8 +123,8 @@ - A static abstract interface member can be accessed only on a type parameter. - A static abstract interface member can be accessed only on a type parameter. + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). + A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.{0}). diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 42b3137064b..48c54e2c11e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -1208,7 +1208,7 @@ IAdditionOperators.op_Addition (3, 6) |> withLangVersion80 |> compile |> shouldFail - |> withSingleDiagnostic (Error 3866, Line 4, Col 1, Line 4, Col 38, "A static abstract interface member can be accessed only on a type parameter.") + |> withSingleDiagnostic (Error 3866, Line 4, Col 1, Line 4, Col 38, "A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.op_Addition).") [] let ``Accessing to IWSAM(System.Numerics virtual member) compiles and runs`` () = @@ -1229,7 +1229,7 @@ printf "%A" res""" #if !NETCOREAPP [] #else - // SOURCE=ConstrainedAndInterfaceCalls.fs # AssemblyVersion01.fs + // SOURCE=ConstrainedAndInterfaceCalls.fs # ConstrainedAndInterfaceCalls.fs [] #endif let ``ConstrainedAndInterfaceCalls.fs`` compilation = @@ -1238,7 +1238,7 @@ printf "%A" res""" |> verifyCompile |> shouldFail |> withDiagnostics [ - (Error 3866, Line 12, Col 82, Line 12, Col 126, "A static abstract interface member can be accessed only on a type parameter.") - (Error 3866, Line 13, Col 82, Line 13, Col 126, "A static abstract interface member can be accessed only on a type parameter.") - (Error 3866, Line 15, Col 82, Line 15, Col 129, "A static abstract interface member can be accessed only on a type parameter.") + (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).") ] \ No newline at end of file