diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index de2fe9821ae6c0eb600c6f2e24164c12677f04ff..9f0239c964ed1b589a72ff330ffb846db3e231d0 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -585,6 +585,10 @@ Signature *ETSChecker::ValidateSignature( size_t const argCount = arguments.size(); auto const hasRestParameter = signature->RestVar() != nullptr; auto const reportError = (flags & TypeRelationFlag::NO_THROW) == 0; + + if (((Relation()->GetTypeRelationFlags() & TypeRelationFlag::REST_ARGS_CONTEXT) != 0) && !hasRestParameter) { + return nullptr; + } size_t compareCount = argCount; if ((flags & TypeRelationFlag::NO_CHECK_TRAILING_LAMBDA) != 0 && !signature->Params().empty() && signature->Params().back()->Declaration()->Node()->AsETSParameterExpression()->IsOptional()) { @@ -1045,14 +1049,7 @@ Signature *ETSChecker::ChooseMostSpecificSignature(ArenaVector &sig return *zeroParamSignature; } // If there are multiple rest parameter signatures with different argument types, throw error - if (signatures.size() > 1 && - std::any_of(signatures.begin(), signatures.end(), [signatures, this](const auto *param) { - auto left = MaybeBoxType(GetElementTypeOfArray(param->RestVar()->TsType())); - auto right = MaybeBoxType(GetElementTypeOfArray(signatures.front()->RestVar()->TsType())); - Relation()->IsIdenticalTo(left, right); - return !Relation()->IsTrue(); - })) { - LogError(diagnostic::AMBIGUOUS_CALL_2, {signatures.front()->Function()->Id()->Name()}, pos); + if (signatures.size() > 1) { return nullptr; } // Else return the signature with the rest parameter diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 733f658a5321354fffcb92de928c42ad72af4540..64f21c5796c6693712e797c2e35776a827ae4288 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -214,11 +214,13 @@ static void AddSignature(std::vector &signatures, PropertySearchFla if (((flags & PropertySearchFlags::IGNORE_ABSTRACT) != 0) && it->HasSignatureFlag(SignatureFlags::ABSTRACT)) { continue; } - if (std::any_of(signatures.begin(), signatures.end(), [&it, &checker](auto sig) { - return checker->AreOverrideCompatible(sig, it) && - it->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE) && - (checker->Relation()->IsSupertypeOf(it->Owner(), sig->Owner()) || - !sig->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE)); + if (!(it->IsFinal() || it->HasSignatureFlag(SignatureFlags::STATIC)) && + std::any_of(signatures.begin(), signatures.end(), [&it, &checker](auto sig) { + return checker->AreOverrideCompatible(it, sig) && + ((checker->Relation()->IsSupertypeOf(it->Owner(), sig->Owner()) && + !checker->Relation()->IsIdenticalTo(it->Owner(), sig->Owner())) || + (it->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE) && + !sig->Owner()->HasObjectFlag(ETSObjectFlags::INTERFACE))); })) { continue; } diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index ae65dc122971ca47b99299b25a816e826a106eca..a3329d57652a422801eb04381e1723c83b70a126 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -63,6 +63,7 @@ enum class TypeRelationFlag : uint32_t { OVERRIDING_CONTEXT = 1U << 25U, IGNORE_REST_PARAM = 1U << 26U, STRING_TO_CHAR = 1U << 27U, + REST_ARGS_CONTEXT = 1U << 28U, ASSIGNMENT_CONTEXT = WIDENING | BOXING | UNBOXING, BRIDGE_CHECK = OVERRIDING_CONTEXT | IGNORE_TYPE_PARAMETERS | NO_RETURN_TYPE_CHECK, diff --git a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp index 224e98033560d2240fcfd1498fc54056b0af6138..1969a16d48071bf9a336bd415b0b5ecf5f241eeb 100644 --- a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp @@ -143,6 +143,7 @@ static ir::CallExpression *RebuildCallExpression(public_lib::Context *context, i auto *scope = NearestScope(newCall->Parent()); auto bscope = varbinder::LexicalScope::Enter(varbinder, scope); + context->checker->Relation()->SetFlags(checker::TypeRelationFlag::REST_ARGS_CONTEXT); CheckLoweredNode(context->checker->VarBinder()->AsETSBinder(), context->checker->AsETSChecker(), newCall); newCall->RemoveAstNodeFlags(ir::AstNodeFlags::RESIZABLE_REST); return newCall; diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets index e53edf414f6b30acaca6e1866c99198e6b8b1df5..1c31c6eb2b01e9fc943c03b5b62594510d0b8744 100644 --- a/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets +++ b/ets2panda/test/ast/compiler/ets/FixedArray/most_specific_method_with_empty_rest_param.ets @@ -26,3 +26,5 @@ function main() { let c: C = new C() c.met() } + +/* @@? 27:5 Error TypeError: Reference to met is ambiguous */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/FixedArray/overload-resolution-rest.ets b/ets2panda/test/ast/compiler/ets/FixedArray/overload-resolution-rest.ets new file mode 100644 index 0000000000000000000000000000000000000000..9dcd5b6a74431456fd31e07f3013701381228b8a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/FixedArray/overload-resolution-rest.ets @@ -0,0 +1,32 @@ +/* + * 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. + */ + +let res: number = 0 + +function foo(a: NullishType) { + res = 1 +} + +function foo(...a: NullishType[]) { + res = 2 +} + +function foo(...a: FixedArray) { + res = 3 +} + +/* @@ label */foo("a", "b", "c", "d") + +/* @@@ label Error TypeError: Reference to foo is ambiguous */ diff --git a/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets b/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets index 7ec8ba7d899bf8deb6ce500629a6e5559edda128..f18d5f61509d19627f253ecd8983ba3be10de54d 100644 --- a/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets +++ b/ets2panda/test/ast/compiler/ets/most_specific_method_with_empty_rest_param.ets @@ -28,3 +28,4 @@ function main() { } /* @@? 20:5 Error TypeError: Function met with this assembly signature already declared. */ +/* @@? 27:5 Error TypeError: Reference to met is ambiguous */ diff --git a/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt b/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt index 74d45b5f1b321a4f27da1dc122b113efe013422a..8984eeaef5b09ea8bf11a9213b4017993f9c9c92 100644 --- a/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt +++ b/ets2panda/test/compiler/ets/functions_with_ambiguous_rest_parameter-expected.txt @@ -904,5 +904,4 @@ } } TypeError: Function foo with this assembly signature already declared. [functions_with_ambiguous_rest_parameter.ets:20:1] -TypeError: Call to `foo` is ambiguous [functions_with_ambiguous_rest_parameter.ets:25:5] TypeError: Reference to foo is ambiguous [functions_with_ambiguous_rest_parameter.ets:25:5] diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 6cb4ab1b329d75524f726121f01dd70180a0a116..d97f7a59c412694ae1bceeb813e5fbdb4a2acc1e 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -523,10 +523,6 @@ semantic: id: 128 message: "No matching {} signature" -- name: AMBIGUOUS_CALL_2 - id: 129 - message: "Call to `{}` is ambiguous " - - name: FUNCTION_REDECL_BY_TYPE_SIG id: 130 message: "Function {} is already declared."