From a7ada651ecd1522ca310393ce01dec9120b0fb35 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 | 5 +++ .../compiler/lowering/ets/recordLowering.cpp | 4 ++ .../ets/objectLiteral_promise_interface.ets | 45 +++++++++++++++++++ 3 files changed, 54 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 97bbfddfb7..909ef18421 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2220,6 +2220,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()); } @@ -2354,6 +2358,7 @@ void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr, } ETSChecker::SetPreferredTypeIfPossible(value, propType); + propExpr->SetTsType(propType); key->SetTsType(propType); value->SetTsType(value->Check(checker)); diff --git a/ets2panda/compiler/lowering/ets/recordLowering.cpp b/ets2panda/compiler/lowering/ets/recordLowering.cpp index 8897cd7ddb..5522c4a3f6 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" @@ -155,6 +156,9 @@ ir::Statement *RecordLowering::CreateStatement(const std::string &src, ir::Expre ir::Expression *RecordLowering::UpdateObjectExpression(ir::ObjectExpression *expr, public_lib::Context *ctx) { auto checker = ctx->checker->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..4ea3743c3d --- /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() + arktest.assertEQ(r1.a, 0) + + let r2 = await foo2() + arktest.assertEQ(r2["b"], 10) + + let r3 = await foo3() + arktest.assertEQ(r3.get("c"), 20) +} + +function main() { + startTest() +} \ No newline at end of file -- Gitee