From c7a48177446b3a5b09680445a1912e9b59ed5a24 Mon Sep 17 00:00:00 2001 From: Daniel Linjama Date: Mon, 23 Oct 2023 10:21:04 +0300 Subject: [PATCH] fix @param-out with named arguments --- .../Expression/Call/ArgumentsAnalyzer.php | 22 ++++++++++++++++++- tests/ReferenceConstraintTest.php | 18 +++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php index 653ffedc9ac..5c9695c87b2 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php @@ -51,6 +51,7 @@ use UnexpectedValueException; use function array_map; +use function array_reduce; use function array_reverse; use function array_slice; use function array_values; @@ -1031,7 +1032,26 @@ private static function handlePossiblyMatchingByRefParam( $check_null_ref = true; if ($last_param) { - if ($argument_offset < count($function_params)) { + if ($arg->name !== null) { + $function_param = array_reduce( + $function_params, + static function ( + ?FunctionLikeParameter $function_param, + FunctionLikeParameter $param + ) use ( + $arg, + ) { + if ($param->name === $arg->name->name) { + return $param; + } + return $function_param; + }, + null, + ); + if ($function_param === null) { + return false; + } + } elseif ($argument_offset < count($function_params)) { $function_param = $function_params[$argument_offset]; } else { $function_param = $last_param; diff --git a/tests/ReferenceConstraintTest.php b/tests/ReferenceConstraintTest.php index 1c6dd4c6aeb..bf1f5d2e43f 100644 --- a/tests/ReferenceConstraintTest.php +++ b/tests/ReferenceConstraintTest.php @@ -193,6 +193,24 @@ function takesNullableObj(?A &$a): bool { return true; } if ($a) {}', ], + 'PHP80-paramOutChangeTypeWithNamedArgument' => [ + 'code' => ' [ + '$a' => 'int', + ], + ], ]; }