diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 110ba4ec5c7262334d34698bc67f69de4ef47232..ecb42e161d373c76f84bb1d58d8057f247c09d81 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -184,7 +184,8 @@ static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinitio ES2PANDA_ASSERT(scriptFunc != nullptr); if (util::Helpers::IsAsyncMethod(node)) { - if (scriptFunc->ReturnTypeAnnotation() != nullptr && scriptFunc->Signature() != nullptr) { + if (scriptFunc->ReturnTypeAnnotation() != nullptr && !scriptFunc->ReturnTypeAnnotation()->IsOpaqueTypeNode() && + scriptFunc->Signature() != nullptr) { auto *asyncFuncReturnType = scriptFunc->Signature()->ReturnType(); if (!asyncFuncReturnType->IsETSObjectType() || @@ -1099,19 +1100,23 @@ checker::Type *ETSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const checker->Context().SetContainingSignature(signature); expr->Function()->Body()->Check(checker); + if (expr->Function()->ReturnTypeAnnotation() == nullptr) { + if (expr->Function()->IsAsyncFunc()) { + auto *retType = signature->ReturnType(); + if (!retType->IsETSObjectType() || + retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { + auto returnType = checker->CreateETSAsyncFuncReturnTypeFromBaseType(signature->ReturnType()); + ES2PANDA_ASSERT(returnType != nullptr); + expr->Function()->Signature()->SetReturnType(returnType->PromiseType()); + for (auto &returnStatement : expr->Function()->ReturnStatements()) { + returnStatement->SetReturnType(checker, returnType); + } + } + } + } auto *funcType = checker->CreateETSArrowType(signature); checker->Context().SetContainingSignature(nullptr); - - if (expr->Function()->IsAsyncFunc()) { - auto *retType = signature->ReturnType(); - if (!retType->IsETSObjectType() || - retType->AsETSObjectType()->GetOriginalBaseType() != checker->GlobalBuiltinPromiseType()) { - checker->LogError(diagnostic::ASYNC_DOESNT_PROMISE, {}, expr->Function()->Start()); - expr->SetTsType(checker->GlobalTypeError()); - return expr->TsType(); - } - } expr->SetTsType(funcType); return expr->TsType(); } diff --git a/ets2panda/test/ast/parser/ets/async_lambda_bad.ets b/ets2panda/test/ast/parser/ets/async_lambda_bad.ets index 702a26d0ced70fc76c75c67ee2f13ba02061e935..addfd7657ba1724ff2cd4ebb67ee3a98a247714e 100644 --- a/ets2panda/test/ast/parser/ets/async_lambda_bad.ets +++ b/ets2panda/test/ast/parser/ets/async_lambda_bad.ets @@ -14,5 +14,3 @@ */ let lambda: () => int = async /* @@ label */(): int => { return 1; } - -/* @@@ label Error TypeError: Return type of async lambda must be 'Promise' */ diff --git a/ets2panda/test/runtime/ets/async_lambda_returntype_infer.ets b/ets2panda/test/runtime/ets/async_lambda_returntype_infer.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b6c246fe722b0689859f47031a3ef3c0687edde --- /dev/null +++ b/ets2panda/test/runtime/ets/async_lambda_returntype_infer.ets @@ -0,0 +1,23 @@ +/* + * 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 f = async () => { return 1 } + +function foo(p: () => Promise) { + return 1; +} +function main(): void { + arktest.assertEQ(foo(f), 1) +} \ No newline at end of file diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 53aa40aaeb92224825696c1f80667bfa47879426..b8b4e1274e552f877df122ff0726f18d202547bc 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -178,10 +178,6 @@ semantic: id: 209 message: "Cannot assign to this property because it is readonly." -- name: ASYNC_DOESNT_PROMISE - id: 23 - message: "Return type of async lambda must be 'Promise'" - - name: ASYNC_FUNCTION_RETURN_TYPE id: 1 message: "Return type of async function must be 'Promise'." @@ -1464,6 +1460,7 @@ graveyard: - 15 - 16 - 22 +- 23 - 29 - 30 - 35