From f56bd745e7e31d03bae804f886281fd110617684 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Fri, 13 Mar 2026 15:43:05 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E5=8C=BF?= =?UTF-8?q?=E5=90=8D=E5=87=BD=E6=95=B0=E8=BF=94=E5=9B=9E=E5=80=BC=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=8E=A8=E6=96=AD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在闭包中强制设置返回值类型为 var,避免类型推断错误 - 保持非闭包函数的原有返回值类型推断逻辑不变 - 添加测试用例验证静态调用场景下的返回值类型处理 --- src/Php/CompilerBase.php | 23 +++++++++++++++-------- tests/aot/func-return-type.phpt | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 tests/aot/func-return-type.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index c71b3145..ee89eef0 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1431,14 +1431,21 @@ class CompilerBase extends \PhpAot\Core\Translator // 实际函数的返回值 $type = $this->detectExprType($v->expr); $expr = $this->parseExpr($v->expr); - // 函数定义时没有声明返回值,但函数体中有返回值,修改为实际的返回值类型 - if ($this->getReturnType() === 'void') { - $this->resetReturnType($v, $type); - } elseif ($this->isNativeType($type) and $this->getReturnType() !== self::TYPE_VAR and $this->getReturnType() !== $type) { - // 返回值类型不一致,说明存在多种类型的返回值,修改为 var 表示 any - $this->resetReturnType($v, self::TYPE_VAR); - } - $returnType = $this->getReturnType(); + + // 匿名函数的返回值一定是 var + if (!$this->inClosure) { + // 函数定义时没有声明返回值,但函数体中有返回值,修改为实际的返回值类型 + if ($this->getReturnType() === 'void') { + $this->resetReturnType($v, $type); + } elseif ($this->isNativeType($type) and $this->getReturnType() !== self::TYPE_VAR and $this->getReturnType() !== $type) { + // 返回值类型不一致,说明存在多种类型的返回值,修改为 var 表示 any + $this->resetReturnType($v, self::TYPE_VAR); + } + $returnType = $this->getReturnType(); + } else { + $returnType = self::TYPE_VAR; + } + $exprCode = $this->convertExprType($expr, $returnType, $type); // return 如果使用了 Indirect 语句,可能会导致变量提前析构,出现悬空指针 // 将 Indirect 赋值给临时变量后,使用 Ctor::Copy 解除了 Indirect,保证内存安全 diff --git a/tests/aot/func-return-type.phpt b/tests/aot/func-return-type.phpt new file mode 100644 index 00000000..55dbc561 --- /dev/null +++ b/tests/aot/func-return-type.phpt @@ -0,0 +1,19 @@ +--TEST-- +static calls +--FILE-- + +--EXPECT-- +string(4) "test" \ No newline at end of file