diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 515f962441ae17bab5115a8307d1e81a4c31139a..c356541eec892b7caeddc9a4837c66fdc74d9c47 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -186,7 +186,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() || @@ -1097,19 +1098,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 67b1ab0c445858c776575813a9752d3a96cba74f..d0d3e5c811cb8f29a687159b1bc880767e729ad2 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -198,10 +198,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'. @@ -1623,6 +1619,7 @@ semantic: graveyard: - 8 +- 23 - 29 - 167 - 233