diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 6f65e600f6800813cb3465f7ffeedcdc21b01117..b82e8e2839a03bf6f07e4616b937084fccf98e9d 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -658,23 +658,10 @@ Signature *ETSChecker::ValidateSignature( size_t const argCount = arguments.size(); auto const hasRestParameter = signature->RestVar() != nullptr; auto const reportError = (flags & TypeRelationFlag::NO_THROW) == 0; - size_t compareCount = argCount; - if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0 && !signature->Params().empty() && - signature->Params().back()->Declaration()->Node()->AsETSParameterExpression()->IsOptional()) { - compareCount = compareCount - 1; - } - - if (compareCount < signature->MinArgCount() || (argCount > signature->ArgCount() && !hasRestParameter)) { - if (reportError) { - LogError(diagnostic::PARAM_COUNT_MISMATCH, {signature->MinArgCount(), argCount}, pos); - } - return nullptr; - } - if (argCount > signature->ArgCount() && hasRestParameter && (flags & TypeRelationFlag::IGNORE_REST_PARAM) != 0) { + if (!ValidateRestParameter(this, signature, arguments, pos, flags)) { return nullptr; } - auto count = std::min(signature->ArgCount(), argCount); // Check all required formal parameter(s) first // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) diff --git a/ets2panda/test/ast/compiler/ets/class_cyclic_constructor.ets b/ets2panda/test/ast/compiler/ets/class_cyclic_constructor.ets index a9dc55d05aab00763ce64ea298e84fdb79a1863f..89afebb59c28b0d63991ab1418a38b63acca1d11 100644 --- a/ets2panda/test/ast/compiler/ets/class_cyclic_constructor.ets +++ b/ets2panda/test/ast/compiler/ets/class_cyclic_constructor.ets @@ -42,9 +42,8 @@ class A { /* @@? 24:34 Error SyntaxError: Unexpected token '='. */ /* @@? 24:36 Error SyntaxError: Unexpected token '{'. */ /* @@? 24:38 Error TypeError: Unresolved reference caches */ -/* @@? 25:21 Error TypeError: Expected 0 arguments, got 1. */ +/* @@? 25:21 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ /* @@? 25:21 Error TypeError: No matching construct signature for class_cyclic_constructor.A(...tuple) */ -/* @@? 25:27 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ /* @@? 25:30 Error TypeError: Unresolved reference tuple */ /* @@? 26:31 Error TypeError: Property 'bar' does not exist on type 'A' */ /* @@? 27:5 Error SyntaxError: Unexpected token ')'. */ diff --git a/ets2panda/test/ast/compiler/ets/spread_record.ets b/ets2panda/test/ast/compiler/ets/spread_record.ets index ec7aa3a9dc41272e5e078e7d845d45ffaddeb229..f9782ab9747c4499a218df40d74a3a8ebcc80400 100644 --- a/ets2panda/test/ast/compiler/ets/spread_record.ets +++ b/ets2panda/test/ast/compiler/ets/spread_record.ets @@ -20,15 +20,12 @@ let r3: Record = { ...r1, ...r2 } console.log(...r3) // crash - Issue #26773 -/* @@? 17:1 Error TypeError: Expected 0 arguments, got 1. */ +/* @@? 17:1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ /* @@? 17:1 Error TypeError: No matching call signature for log(...r1) */ -/* @@? 17:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ +/* @@? 17:1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ /* @@? 17:13 Error TypeError: Type 'Record' is not compatible with rest parameter type 'Array' at index 1 */ /* @@? 17:13 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Record' is provided */ -/* @@? 17:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ /* @@? 20:1 Error TypeError: No matching call signature for log(...r3) */ -/* @@? 20:1 Error TypeError: Expected 0 arguments, got 1. */ -/* @@? 20:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ +/* @@? 20:1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ /* @@? 20:13 Error TypeError: Type 'Record' is not compatible with rest parameter type 'Array' at index 1 */ /* @@? 20:13 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Record' is provided */ -/* @@? 20:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets index a97e3450fc1f571d6ce4b5ee4f690eb2bc8d458a..ca67a0dc01cff69925ce9368359eeb384ac33918 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/MultipleParserErrors.ets @@ -226,10 +226,12 @@ function main(): void { /* @@? 92:7 Error TypeError: Variable 'A' has already been declared. */ /* @@? 92:7 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ /* @@? 93:3 Error SyntaxError: Unexpected token. A constructor, method, accessor, or property was expected. */ -/* @@? 115:26 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 103:14 Error SyntaxError: Rest parameter should be either array or tuple type. */ +/* @@? 104:21 Error SyntaxError: Rest parameter should be either array or tuple type. */ /* @@? 115:26 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 115:26 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 115:26 Error SyntaxError: Unexpected token 'case'. */ +/* @@? 115:26 Error SyntaxError: Unexpected token, expected an identifier. */ /* @@? 115:30 Error SyntaxError: Unexpected token ':'. */ /* @@? 115:32 Error SyntaxError: Unexpected token 'U'. */ /* @@? 115:32 Error TypeError: Unresolved reference U */ diff --git a/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_1.ets b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..26483b2780137c4e697099b19173c07c0e83d3ab --- /dev/null +++ b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_1.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo(x: number) { + console.log(x) +} +let args_tuple: [number, number] = [0, 1] +/* @@ label1 */foo(1, ...args_tuple) +let args_array: number[] = [2, 3] +/* @@ label2 */foo(4, ...args_array) + +/* @@@ label1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label1 Error TypeError: No matching call signature for foo(Int, [Double, Double]) */ +/* @@@ label2 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label2 Error TypeError: No matching call signature for foo(Int, Double) */ diff --git a/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_2.ets b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..a5407b76f91f8ed4787688a74ea581267c105884 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_2.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo(x: number) { + console.log(x) +} +let args_tuple: [number, number] = [0, 1] +/* @@ label1 */foo(...args_tuple) +let args_array: number[] = [2, 3] +/* @@ label2 */foo(...args_array) + +function moo(x: number, y: number) { + console.log(x, y) +} +args_tuple = [0, 1] +/* @@ label3 */moo(1, ...args_tuple) +args_array = [2, 3] +/* @@ label4 */moo(2, ...args_array) + +/* @@@ label1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label1 Error TypeError: No matching call signature for foo([Double, Double]) */ +/* @@@ label2 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label2 Error TypeError: No matching call signature for foo(Double) */ +/* @@@ label3 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label3 Error TypeError: No matching call signature for moo(Int, [Double, Double]) */ +/* @@@ label4 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label4 Error TypeError: No matching call signature for moo(Int, Double) */ diff --git a/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_3.ets b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..89d5215fd1226415488589ea8be4a8376171f4aa --- /dev/null +++ b/ets2panda/test/ast/parser/ets/spread_parameter_only_with_rest_3.ets @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function foo(x: number, y: number) { + console.log(x, y) +} +let args_tuple: [number, number] = [0, 1] +/* @@ label1 */foo(...args_tuple) +let args_array: number[] = [2, 3] +/* @@ label2 */foo(...args_array) + +function moo(x: number, y: number, z: number) { + console.log(x, y, z) +} +args_tuple = [0, 1] +/* @@ label3 */moo(1, ...args_tuple) +args_array = [2, 3] +/* @@ label4 */moo(2, ...args_array) + +/* @@@ label1 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label1 Error TypeError: No matching call signature for foo([Double, Double]) */ +/* @@@ label2 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label2 Error TypeError: No matching call signature for foo(Double) */ +/* @@@ label3 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label3 Error TypeError: No matching call signature for moo(Int, [Double, Double]) */ +/* @@@ label4 Error TypeError: The function or method being called needs a rest parameter to accept arguments passed via the spread operator. */ +/* @@@ label4 Error TypeError: No matching call signature for moo(Int, Double) */ diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 67b1ab0c445858c776575813a9752d3a96cba74f..7bb8b93fb591a0a664e062a2ded9a6620517824c 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -471,6 +471,10 @@ semantic: id: 343 message: "Indexed signatures are not allowed. Use arrays instead!" +- name: ERROR_ARKTS_SPREAD_ONLY_WITH_REST + id: 44192 + message: "The function or method being called needs a rest parameter to accept arguments passed via the spread operator." + - name: EXCEPTION_REDECLARATION id: 13 message: "Redeclaration of exception type"