Skip to content

Commit

Permalink
Fix how well conditional types play with pre-existing @param-out va…
Browse files Browse the repository at this point in the history
…riable after assignment
  • Loading branch information
ondrejmirtes committed Sep 3, 2024
1 parent 2b97628 commit 5892e8d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand All @@ -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);
}
Expand Down
35 changes: 35 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-11580.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Bug11580;

use function PHPStan\Testing\assertType;

final class HelloWorld
{
public function bad(string $in): void
{
$matches = [];
if (preg_match('~^/xxx/([\w\-]+)/?([\w\-]+)?/?$~', $in, $matches)) {
assertType('array{0: string, 1: non-empty-string, 2?: non-empty-string}', $matches);
}
}

public function bad2(string $in): void
{
$matches = [];
$result = preg_match('~^/xxx/([\w\-]+)/?([\w\-]+)?/?$~', $in, $matches);
if ($result) {
assertType('array{0: string, 1: non-empty-string, 2?: non-empty-string}', $matches);
}
}

public function bad3(string $in): void
{
$result = preg_match('~^/xxx/([\w\-]+)/?([\w\-]+)?/?$~', $in, $matches);
assertType('array{0?: string, 1?: non-empty-string, 2?: non-empty-string}', $matches);
if ($result) {
assertType('array{0: string, 1: non-empty-string, 2?: non-empty-string}', $matches);
}
}

}
4 changes: 2 additions & 2 deletions tests/PHPStan/Analyser/nsrt/bug-7805.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ function foo(array $params)
assertNativeType("array<mixed~'help', mixed>", $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);
Expand Down

0 comments on commit 5892e8d

Please sign in to comment.