From d480c5e7cbe9e9f00967ca8c55acb4c704bd911d Mon Sep 17 00:00:00 2001 From: hafung <32428762+hafung@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:47:16 +0800 Subject: [PATCH] fix(optimizer): preserve array_keys strict type errors --- src/Optimizer/FuncCallOptimizer.php | 5 +- .../stdlib/array-keys-dynamic-arguments.phpt | 52 ++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/Optimizer/FuncCallOptimizer.php b/src/Optimizer/FuncCallOptimizer.php index 4e60b055..6d06b9eb 100644 --- a/src/Optimizer/FuncCallOptimizer.php +++ b/src/Optimizer/FuncCallOptimizer.php @@ -766,10 +766,13 @@ trait FuncCallOptimizer return 'php::fn::get_parent_class(' . $this->parseIdentifier($arg) . ')'; } - protected function genArrayKeys(string $n, Node\Expr\FuncCall $e, array $c): string + protected function genArrayKeys(string $n, Node\Expr\FuncCall $e, array $c): string|false { $cnt = count($e->args); if ($cnt >= 3) { + if ($this->detectTypeOfExpr($e->args[2]->value) !== Type::BOOL) { + return false; + } return 'php::fn::array_keys_filter(' . $this->getArg($e, 0) . ', ' . $this->getArg($e, 1) . ', ' . $this->resolveArg($e, 2, self::ARG_TYPE_BOOL) . ')'; } diff --git a/tests/compiler/stdlib/array-keys-dynamic-arguments.phpt b/tests/compiler/stdlib/array-keys-dynamic-arguments.phpt index b89e4cbd..eb156c36 100644 --- a/tests/compiler/stdlib/array-keys-dynamic-arguments.phpt +++ b/tests/compiler/stdlib/array-keys-dynamic-arguments.phpt @@ -1,5 +1,5 @@ --TEST-- -array_keys optimized calls convert dynamic arguments and preserve evaluation order +array_keys optimized calls preserve dynamic arguments, strict types, and evaluation order --FILE-- 1, 'string' => '1']; @@ -48,6 +68,29 @@ function main() arrayKeysDynamicStrict($events) )); var_dump($events); + + var_dump(array_keys($values, '1', arrayKeysMixedBool())); + + try { + array_keys($values, '1', arrayKeysMixedInt()); + echo "mixed-int=missing TypeError\n"; + } catch (TypeError $error) { + echo "mixed-int=TypeError\n"; + } + + try { + array_keys($values, '1', arrayKeysMixedArray()); + echo "mixed-array=missing TypeError\n"; + } catch (TypeError $error) { + echo "mixed-array=TypeError\n"; + } + + try { + array_keys($values, '1', arrayKeysUnionInt()); + echo "union-int=missing TypeError\n"; + } catch (TypeError $error) { + echo "union-int=TypeError\n"; + } } ?> --EXPECT-- @@ -87,3 +130,10 @@ array(3) { [2]=> string(6) "strict" } +array(1) { + [0]=> + string(6) "string" +} +mixed-int=TypeError +mixed-array=TypeError +union-int=TypeError