From 82ed8599e1307ce624db2909fd08e228d6040a81 Mon Sep 17 00:00:00 2001 From: ijklam Date: Sun, 11 Feb 2024 16:34:59 +0800 Subject: [PATCH 1/3] Allow calling method with both Optional and ParamArray --- src/Compiler/Checking/MethodCalls.fs | 7 +++++ .../BasicGrammarElements/MethodResolution.fs | 31 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs index 5aed55cba0..1b31e526f8 100644 --- a/src/Compiler/Checking/MethodCalls.fs +++ b/src/Compiler/Checking/MethodCalls.fs @@ -556,6 +556,13 @@ type CalledMeth<'T> let nUnnamedCalledArgs = unnamedCalledArgs.Length if allowOutAndOptArgs && nUnnamedCallerArgs < nUnnamedCalledArgs then let unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs = List.splitAt nUnnamedCallerArgs unnamedCalledArgs + + // take the last ParamArray arg out, make it not break the optional/out params check + let unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs = + match List.rev unnamedCalledOptOrOutArgs with + | [] -> unnamedCalledArgsTrimmed, [] + | h :: t when h.IsParamArray -> unnamedCalledArgsTrimmed @ [h], List.rev t + | _ -> unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs let isOpt x = x.OptArgInfo.IsOptional let isOut x = x.IsOutArg && isByrefTy g x.CalledArgumentType diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs index 613001af65..3ac3d49ce4 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs @@ -262,3 +262,34 @@ let _, _ = Thing.Do() (Error 501, Line 6, Col 12, Line 6, Col 22, "The member or object constructor 'Do' takes 1 argument(s) but is here given 0. The required signature is 'static member Thing.Do: [] i: outref -> bool'.") ] + [] + let ``optional and ParamArray parameter resolves correctly `` () = + Fsx """ +open System.Runtime.InteropServices + +type Thing = + static member Do( + [] something: string, + [] args: obj[]) = something, args + static member Do2( + [] something: string, + outvar: outref, + [] args: obj[]) = + + outvar <- 1 + something, args +let _, _ = Thing.Do() +let _, _ = Thing.Do("123") +let _, _ = Thing.Do("123", 1, 2, 3, 4) + +let _, _ = Thing.Do2() +let _, _ = Thing.Do2("123") +let _ = + let mutable x = 0 + Thing.Do2("123", &x) +let _ = + let mutable x = 0 + Thing.Do2("123", &x, 1, 2, 3, 4) + """ + |> typecheck + |> shouldSucceed From bc8348e210eab59f187443e28947f01e61fa5a89 Mon Sep 17 00:00:00 2001 From: ijklam Date: Sun, 11 Feb 2024 16:44:59 +0800 Subject: [PATCH 2/3] release note --- docs/release-notes/.FSharp.Compiler.Service/8.0.300.md | 1 + 1 file changed, 1 insertion(+) 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 6a4d44d2ae..86bab0f30b 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -9,6 +9,7 @@ * Fix crash in DOTNET_SYSTEM_GLOBALIZATION_INVARIANT mode ([PR #16471](https://github.com/dotnet/fsharp/pull/16471)) * `[]` member should not produce property symbol. ([Issue #16640](https://github.com/dotnet/fsharp/issues/16640), [PR #16658](https://github.com/dotnet/fsharp/pull/16658)) * Fix discriminated union initialization. ([#PR 16661](https://github.com/dotnet/fsharp/pull/16661)) +* Allow calling method with both Optional and ParamArray. ([#PR 16688](https://github.com/dotnet/fsharp/pull/16688), [suggestions #1120](https://github.com/fsharp/fslang-suggestions/issues/1120)) ### Added From 3c2d958793fb4731a8eb8be70c6417164f045418 Mon Sep 17 00:00:00 2001 From: ijklam <43789618+Tangent-90@users.noreply.github.com> Date: Sun, 11 Feb 2024 16:51:19 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20MethodCalls.fs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Compiler/Checking/MethodCalls.fs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs index 1b31e526f8..5f60bfce12 100644 --- a/src/Compiler/Checking/MethodCalls.fs +++ b/src/Compiler/Checking/MethodCalls.fs @@ -560,7 +560,6 @@ type CalledMeth<'T> // take the last ParamArray arg out, make it not break the optional/out params check let unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs = match List.rev unnamedCalledOptOrOutArgs with - | [] -> unnamedCalledArgsTrimmed, [] | h :: t when h.IsParamArray -> unnamedCalledArgsTrimmed @ [h], List.rev t | _ -> unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs