diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index b7d1a386e70f2c2b8537470e0e73d55134783d2c..fec07d7ba6f59a2e482cacb6e87a74a72e0db6c6 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2563,17 +2563,26 @@ void ETSChecker::InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunction continue; } auto *const lambdaParam = lambda->Params().at(i)->AsETSParameterExpression()->Ident(); - if (lambdaParam->TypeAnnotation() == nullptr) { - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - Type *inferredType = calleeType->Params()[i]->AsETSParameterExpression()->TypeAnnotation()->Check(this); - bool isPrimitive = inferredType != nullptr && inferredType->IsETSPrimitiveType(); - if (!isPrimitive && maybeSubstitutedFunctionSig != nullptr) { - ES2PANDA_ASSERT(maybeSubstitutedFunctionSig->Params().size() == calleeType->Params().size()); + if (lambdaParam->TypeAnnotation() != nullptr) { + continue; + } + + // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) + Type *inferredType = calleeType->Params()[i]->AsETSParameterExpression()->TypeAnnotation()->Check(this); + bool isPrimitive = inferredType != nullptr && inferredType->IsETSPrimitiveType(); + if (!isPrimitive && maybeSubstitutedFunctionSig != nullptr) { + auto sigParamSize = maybeSubstitutedFunctionSig->Params().size(); + ES2PANDA_ASSERT( + sigParamSize == calleeType->Params().size() || + (maybeSubstitutedFunctionSig->HasRestParameter() && sigParamSize <= calleeType->Params().size())); + if (i < sigParamSize) { inferredType = maybeSubstitutedFunctionSig->Params()[i]->TsType(); + } else if (!maybeSubstitutedFunctionSig->RestVar()->TsType()->IsETSTupleType()) { + inferredType = GetElementTypeOfArray(maybeSubstitutedFunctionSig->RestVar()->TsType()); } - lambdaParam->Variable()->SetTsType(inferredType); - lambdaParam->SetTsType(inferredType); } + lambdaParam->Variable()->SetTsType(inferredType); + lambdaParam->SetTsType(inferredType); } if (lambda->ReturnTypeAnnotation() == nullptr) { diff --git a/ets2panda/test/ast/compiler/ets/lambda_type_infer_to_rest_type.ets b/ets2panda/test/ast/compiler/ets/lambda_type_infer_to_rest_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a449142937d531082b2386380346a1e3776f39b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/lambda_type_infer_to_rest_type.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + +declare function testRest(a: (t: T, t1: T, ...ts: T[]) => void): T + +testRest((t1:number, t2:boolean, t3) => {}) + +/* @@? 18:10 Error TypeError: Type '(t1: Double, t2: Boolean, t3: never) => void' is not compatible with type '(t: never, t1: never, ...ts: Array) => void' at index 1 */