Skip to content

Commit 3ed174f

Browse files
committed
Fix forgetting expressions on function calls / closure invoke
1 parent 1ab3930 commit 3ed174f

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,6 +2597,16 @@ static function (): void {
25972597
$throwPoints[] = ThrowPoint::createImplicit($scope, $expr);
25982598
}
25992599

2600+
if (
2601+
(
2602+
($functionReflection !== null && $functionReflection->hasSideEffects()->yes())
2603+
|| $parametersAcceptor instanceof ClosureType && $parametersAcceptor->getReturnType()->isVoid()->yes()
2604+
)
2605+
&& $scope->isInClass()
2606+
) {
2607+
$scope = $scope->invalidateExpression(new Variable('this'), true);
2608+
}
2609+
26002610
if (
26012611
$functionReflection !== null
26022612
&& in_array($functionReflection->getName(), ['json_encode', 'json_decode'], true)
@@ -3022,13 +3032,11 @@ static function (): void {
30223032

30233033
if (
30243034
$methodReflection !== null
3025-
&& !$methodReflection->isStatic()
30263035
&& (
30273036
$methodReflection->hasSideEffects()->yes()
30283037
|| $methodReflection->getName() === '__construct'
30293038
)
30303039
&& $scopeFunction instanceof MethodReflection
3031-
&& !$scopeFunction->isStatic()
30323040
&& $scope->isInClass()
30333041
&& $scope->getClassReflection()->is($methodReflection->getDeclaringClass()->getName())
30343042
) {

tests/PHPStan/Rules/Methods/NullsafeMethodCallRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,14 @@ public function testBug6922b(): void
5555
$this->analyse([__DIR__ . '/data/bug-6922b.php'], []);
5656
}
5757

58+
public function testBug8523(): void
59+
{
60+
$this->analyse([__DIR__ . '/data/bug-8523.php'], []);
61+
}
62+
63+
public function testBug8523b(): void
64+
{
65+
$this->analyse([__DIR__ . '/data/bug-8523b.php'], []);
66+
}
67+
5868
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Bug8523;
4+
5+
class HelloWorld
6+
{
7+
public static ?HelloWorld $instance = null;
8+
9+
public static function bazz(): void
10+
{
11+
self::$instance = null;
12+
}
13+
14+
public function foo(): void
15+
{
16+
self::$instance = new HelloWorld();
17+
18+
self::bazz();
19+
20+
self::$instance?->foo();
21+
}
22+
23+
public function bar(): void
24+
{
25+
self::$instance = null;
26+
}
27+
28+
public function baz(): void
29+
{
30+
self::$instance = new HelloWorld();
31+
32+
$this->bar();
33+
34+
self::$instance?->foo();
35+
}
36+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug8523b;
4+
5+
class HelloWorld
6+
{
7+
public static ?HelloWorld $instance = null;
8+
9+
public function save(): void {
10+
self::$instance = new HelloWorld();
11+
12+
$callback = static function(): void {
13+
self::$instance = null;
14+
};
15+
16+
$callback();
17+
18+
var_dump(self::$instance);
19+
20+
self::$instance?->save();
21+
}
22+
}
23+
24+
(new HelloWorld())->save();

0 commit comments

Comments
 (0)