Skip to content

Commit 921ec7c

Browse files
authored
Allow calling method with both Optional and ParamArray (dotnet#16688)
* Allow calling method with both Optional and ParamArray * release note * 更新 MethodCalls.fs
1 parent f6f49b6 commit 921ec7c

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

docs/release-notes/.FSharp.Compiler.Service/8.0.300.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* Fix16572 - Fixed the preview feature enabling Is properties for union case did not work correctly with let .rec and .fsi files ([PR #16657](https://github.com/dotnet/fsharp/pull/16657))
1111
* `[<CliEvent>]` member should not produce property symbol. ([Issue #16640](https://github.com/dotnet/fsharp/issues/16640), [PR #16658](https://github.com/dotnet/fsharp/pull/16658))
1212
* Fix discriminated union initialization. ([#PR 16661](https://github.com/dotnet/fsharp/pull/16661))
13+
* 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))
1314

1415
### Added
1516

src/Compiler/Checking/MethodCalls.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,12 @@ type CalledMeth<'T>
556556
let nUnnamedCalledArgs = unnamedCalledArgs.Length
557557
if allowOutAndOptArgs && nUnnamedCallerArgs < nUnnamedCalledArgs then
558558
let unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs = List.splitAt nUnnamedCallerArgs unnamedCalledArgs
559+
560+
// take the last ParamArray arg out, make it not break the optional/out params check
561+
let unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs =
562+
match List.rev unnamedCalledOptOrOutArgs with
563+
| h :: t when h.IsParamArray -> unnamedCalledArgsTrimmed @ [h], List.rev t
564+
| _ -> unnamedCalledArgsTrimmed, unnamedCalledOptOrOutArgs
559565

560566
let isOpt x = x.OptArgInfo.IsOptional
561567
let isOut x = x.IsOutArg && isByrefTy g x.CalledArgumentType

tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,34 @@ let _, _ = Thing.Do()
262262
(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: [<Optional>] i: outref<bool> -> bool'.")
263263
]
264264

265+
[<Fact>]
266+
let ``optional and ParamArray parameter resolves correctly `` () =
267+
Fsx """
268+
open System.Runtime.InteropServices
269+
270+
type Thing =
271+
static member Do(
272+
[<Optional; DefaultParameterValue "">] something: string,
273+
[<System.ParamArray>] args: obj[]) = something, args
274+
static member Do2(
275+
[<Optional; DefaultParameterValue "">] something: string,
276+
outvar: outref<int>,
277+
[<System.ParamArray>] args: obj[]) =
278+
279+
outvar <- 1
280+
something, args
281+
let _, _ = Thing.Do()
282+
let _, _ = Thing.Do("123")
283+
let _, _ = Thing.Do("123", 1, 2, 3, 4)
284+
285+
let _, _ = Thing.Do2()
286+
let _, _ = Thing.Do2("123")
287+
let _ =
288+
let mutable x = 0
289+
Thing.Do2("123", &x)
290+
let _ =
291+
let mutable x = 0
292+
Thing.Do2("123", &x, 1, 2, 3, 4)
293+
"""
294+
|> typecheck
295+
|> shouldSucceed

0 commit comments

Comments
 (0)