Skip to content

Commit 7026bca

Browse files
committed
Do not create conditional expressions of unrelated variables
1 parent baa371e commit 7026bca

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,6 +2977,7 @@ private function processAssignVar(
29772977
$result = $processExprCallback($scope);
29782978
$hasYield = $result->hasYield();
29792979
$throwPoints = $result->getThrowPoints();
2980+
$assignedExpr = $this->unwrapAssign($assignedExpr);
29802981
$type = $scope->getType($assignedExpr);
29812982
$truthySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createTruthy());
29822983
$falseySpecifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $assignedExpr, TypeSpecifierContext::createFalsey());
@@ -3167,6 +3168,15 @@ private function processAssignVar(
31673168
return new ExpressionResult($scope, $hasYield, $throwPoints);
31683169
}
31693170

3171+
private function unwrapAssign(Expr $expr): Expr
3172+
{
3173+
if ($expr instanceof Assign) {
3174+
return $this->unwrapAssign($expr->expr);
3175+
}
3176+
3177+
return $expr;
3178+
}
3179+
31703180
/**
31713181
* @param Scope $scope
31723182
* @param string $variableName

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10338,6 +10338,7 @@ public function dataFileAsserts(): iterable
1033810338
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4287.php');
1033910339
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-4700.php');
1034010340
yield from $this->gatherAssertTypes(__DIR__ . '/data/phpdoc-in-closure-bind.php');
10341+
yield from $this->gatherAssertTypes(__DIR__ . '/data/multi-assign.php');
1034110342
}
1034210343

1034310344
/**
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
namespace MultiAssign;
4+
5+
use function PHPStan\Analyser\assertType;
6+
7+
function (): void {
8+
$foo = $bar = $baz = null;
9+
assertType('null', $foo);
10+
assertType('null', $bar);
11+
assertType('null', $baz);
12+
if (!$foo) {
13+
assertType('null', $foo);
14+
assertType('null', $bar);
15+
assertType('null', $baz);
16+
}
17+
18+
if (!$bar) {
19+
assertType('null', $foo);
20+
assertType('null', $bar);
21+
assertType('null', $baz);
22+
}
23+
};
24+
25+
function (bool $b): void {
26+
$foo = $bar = $baz = $b;
27+
if ($b) {
28+
assertType('true', $b);
29+
assertType('bool', $foo);
30+
assertType('bool', $bar);
31+
assertType('bool', $baz);
32+
} else {
33+
assertType('false', $b);
34+
assertType('bool', $foo);
35+
assertType('bool', $bar);
36+
assertType('bool', $baz);
37+
}
38+
};
39+
40+
function (bool $b): void {
41+
$foo = $bar = $baz = $b;
42+
if ($foo) {
43+
assertType('true', $b);
44+
assertType('true', $foo);
45+
assertType('bool', $bar);
46+
assertType('bool', $baz);
47+
} else {
48+
assertType('false', $b);
49+
assertType('false', $foo);
50+
assertType('bool', $bar);
51+
assertType('bool', $baz);
52+
}
53+
};
54+
55+
function (bool $b): void {
56+
$foo = $bar = $baz = $b;
57+
if ($bar) {
58+
assertType('bool', $b);
59+
assertType('bool', $foo);
60+
assertType('true', $bar);
61+
assertType('bool', $baz);
62+
} else {
63+
assertType('bool', $b);
64+
assertType('bool', $foo);
65+
assertType('false', $bar);
66+
assertType('bool', $baz);
67+
}
68+
};
69+
70+
function (bool $b): void {
71+
$foo = $bar = $baz = $b;
72+
if ($baz) {
73+
assertType('bool', $b);
74+
assertType('bool', $foo);
75+
assertType('bool', $bar);
76+
assertType('true', $baz);
77+
} else {
78+
assertType('bool', $b);
79+
assertType('bool', $foo);
80+
assertType('bool', $bar);
81+
assertType('false', $baz);
82+
}
83+
};

0 commit comments

Comments
 (0)