Skip to content

Commit 35ff689

Browse files
committed
Fix property assign not being an impure point in arrow function
1 parent 702ddcd commit 35ff689

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

src/Analyser/MutatingScope.php

+24-3
Original file line numberDiff line numberDiff line change
@@ -1272,17 +1272,38 @@ private function resolveType(string $exprString, Expr $node): Type
12721272
}
12731273
}
12741274

1275+
$arrowFunctionImpurePoints = [];
1276+
$invalidateExpressions = [];
12751277
$arrowFunctionExprResult = $this->nodeScopeResolver->processExprNode(
12761278
new Node\Stmt\Expression($node->expr),
12771279
$node->expr,
12781280
$arrowScope,
1279-
static function (): void {
1281+
static function (Node $node, Scope $scope) use ($arrowScope, &$arrowFunctionImpurePoints, &$invalidateExpressions): void {
1282+
if ($scope->getAnonymousFunctionReflection() !== $arrowScope->getAnonymousFunctionReflection()) {
1283+
return;
1284+
}
1285+
1286+
if ($node instanceof InvalidateExprNode) {
1287+
$invalidateExpressions[] = $node;
1288+
return;
1289+
}
1290+
1291+
if (!$node instanceof PropertyAssignNode) {
1292+
return;
1293+
}
1294+
1295+
$arrowFunctionImpurePoints[] = new ImpurePoint(
1296+
$scope,
1297+
$node,
1298+
'propertyAssign',
1299+
'property assignment',
1300+
true,
1301+
);
12801302
},
12811303
ExpressionContext::createDeep(),
12821304
);
12831305
$throwPoints = $arrowFunctionExprResult->getThrowPoints();
1284-
$impurePoints = $arrowFunctionExprResult->getImpurePoints();
1285-
$invalidateExpressions = [];
1306+
$impurePoints = array_merge($arrowFunctionImpurePoints, $arrowFunctionExprResult->getImpurePoints());
12861307
$usedVariables = [];
12871308
} else {
12881309
$closureScope = $this->enterAnonymousFunctionWithoutReflection($node, $callableParameters);

tests/PHPStan/Rules/DeadCode/BetterNoopRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Node\Printer\Printer;
77
use PHPStan\Rules\Rule;
88
use PHPStan\Testing\RuleTestCase;
9+
use const PHP_VERSION_ID;
910

1011
/**
1112
* @extends RuleTestCase<BetterNoopRule>
@@ -145,6 +146,10 @@ public function testRuleImpurePoints(): void
145146

146147
public function testBug11001(): void
147148
{
149+
if (PHP_VERSION_ID < 70400) {
150+
self::markTestSkipped('Test requires PHP 7.4.');
151+
}
152+
148153
$this->analyse([__DIR__ . '/data/bug-11001.php'], []);
149154
}
150155

tests/PHPStan/Rules/DeadCode/data/bug-11001.php

+15
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,18 @@ public function doFoo(): void
2121
}
2222

2323
}
24+
25+
class Foo2
26+
{
27+
public function test(): void
28+
{
29+
\Closure::bind(fn () => $this->status = 5, $this)();
30+
}
31+
32+
public function test2(): void
33+
{
34+
\Closure::bind(function () {
35+
$this->status = 5;
36+
}, $this)();
37+
}
38+
}

0 commit comments

Comments
 (0)