From fe3c1f4fc0668e9a29f7c5f10b58b03a7abd6c5b Mon Sep 17 00:00:00 2001 From: fcc Date: Wed, 11 Jun 2025 11:46:25 +0800 Subject: [PATCH] fix return object literal as Promise type When function signature requires a Promise of interface as return type, and it actually returns object literal, there should be no CTE. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICE95T Signed-off-by: fcc --- ets2panda/checker/ETSAnalyzer.cpp | 4 ++ .../compiler/lowering/ets/recordLowering.cpp | 4 ++ .../ets/objectLiteral_promise_interface.ets | 45 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 ets2panda/test/runtime/ets/objectLiteral_promise_interface.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 3aa4109c2e..c0a5b12d2c 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2204,6 +2204,10 @@ static checker::ETSObjectType *ResolveObjectTypeFromPreferredType(ETSChecker *ch // Assume not null, checked by caller in Check() checker::Type *preferredType = expr->PreferredType(); + if (preferredType->IsETSAsyncFuncReturnType()) { + preferredType = preferredType->AsETSAsyncFuncReturnType()->GetPromiseTypeArg(); + } + if (preferredType->IsETSUnionType()) { return ResolveUnionObjectTypeForObjectLiteral(checker, expr, preferredType->AsETSUnionType()); } diff --git a/ets2panda/compiler/lowering/ets/recordLowering.cpp b/ets2panda/compiler/lowering/ets/recordLowering.cpp index ae3026ab95..739bd43a49 100644 --- a/ets2panda/compiler/lowering/ets/recordLowering.cpp +++ b/ets2panda/compiler/lowering/ets/recordLowering.cpp @@ -16,6 +16,7 @@ #include "recordLowering.h" #include "checker/ETSchecker.h" +#include "checker/types/ets/etsAsyncFuncReturnType.h" #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "compiler/lowering/util.h" @@ -169,6 +170,9 @@ void RecordLowering::CheckKeyType(checker::ETSChecker *checker, checker::Type co ir::Expression *RecordLowering::UpdateObjectExpression(ir::ObjectExpression *expr, public_lib::Context *ctx) { auto checker = ctx->GetChecker()->AsETSChecker(); + if (expr->PreferredType()->IsETSAsyncFuncReturnType()) { + expr->SetPreferredType(expr->PreferredType()->AsETSAsyncFuncReturnType()->GetPromiseTypeArg()); + } if (!expr->PreferredType()->IsETSObjectType()) { // Unexpected preferred type diff --git a/ets2panda/test/runtime/ets/objectLiteral_promise_interface.ets b/ets2panda/test/runtime/ets/objectLiteral_promise_interface.ets new file mode 100644 index 0000000000..c72939f812 --- /dev/null +++ b/ets2panda/test/runtime/ets/objectLiteral_promise_interface.ets @@ -0,0 +1,45 @@ +/* + * 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. + */ + +interface Foo { + a: int +} + +async function foo1() : Promise { + return { a: 0 } +} + +async function foo2() : Promise> { + return { "b": 10 } +} + +async function foo3() : Promise> { + return { "c": 20 } +} + +async function startTest() { + let r1 = await foo1() + assertEQ(r1.a, 0) + + let r2 = await foo2() + assertEQ(r2["b"], 10) + + let r3 = await foo3() + assertEQ(r3.get("c"), 20) +} + +function main() { + startTest() +} \ No newline at end of file -- Gitee