From 5892e8debfbe2f44306e6707c457665784b7dacd Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 3 Sep 2024 21:08:59 +0200 Subject: [PATCH] Fix how well conditional types play with pre-existing `@param-out` variable after assignment --- src/Analyser/NodeScopeResolver.php | 3 +- tests/PHPStan/Analyser/nsrt/bug-11580.php | 35 +++++++++++++++++++++++ tests/PHPStan/Analyser/nsrt/bug-7805.php | 4 +-- 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 tests/PHPStan/Analyser/nsrt/bug-11580.php diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index a885d648b..b22d651f9 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -4953,6 +4953,7 @@ private function processAssignVar( } } + $scope = $result->getScope(); $truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createTruthy()); $falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createFalsey()); @@ -4965,7 +4966,7 @@ private function processAssignVar( $conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType); $nodeCallback(new VariableAssignNode($var, $assignedExpr, $isAssignOp), $result->getScope()); - $scope = $result->getScope()->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr)); + $scope = $scope->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr)); foreach ($conditionalExpressions as $exprString => $holders) { $scope = $scope->addConditionalExpressions($exprString, $holders); } diff --git a/tests/PHPStan/Analyser/nsrt/bug-11580.php b/tests/PHPStan/Analyser/nsrt/bug-11580.php new file mode 100644 index 000000000..ebb422037 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-11580.php @@ -0,0 +1,35 @@ +", $params); $params = $params === [] ? ['list'] : $params; assertType("array{'list'}", $params); - assertNativeType("non-empty-array", $params); + assertNativeType("array{'list'}", $params); array_unshift($params, 'help'); assertType("array{'help', 'list'}", $params); - assertNativeType("non-empty-array", $params); + assertNativeType("array{'help', 'list'}", $params); } assertType("array{}|array{'help', 'list'}", $params); assertNativeType('array', $params);