Skip to content

Commit 15b80c3

Browse files
committed
Fix args are mistakenly handled as immediately-invoked
1 parent 8ae740c commit 15b80c3

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5139,7 +5139,13 @@ private function processArgs(
51395139
$scopeToPass = $closureBindScope;
51405140
}
51415141

5142-
if ($parameter instanceof ExtendedParameterReflection) {
5142+
if (
5143+
$parameterType === null
5144+
|| $parameterType instanceof MixedType
5145+
|| $parameterType->isCallable()->no()
5146+
) {
5147+
$callCallbackImmediately = false;
5148+
} elseif ($parameter instanceof ExtendedParameterReflection) {
51435149
$parameterCallImmediately = $parameter->isImmediatelyInvokedCallable();
51445150
if ($parameterCallImmediately->maybe()) {
51455151
$callCallbackImmediately = $calleeReflection instanceof FunctionReflection;
@@ -5149,6 +5155,7 @@ private function processArgs(
51495155
} else {
51505156
$callCallbackImmediately = $calleeReflection instanceof FunctionReflection;
51515157
}
5158+
51525159
if ($arg->value instanceof Expr\Closure) {
51535160
$restoreThisScope = null;
51545161
if (

tests/PHPStan/Analyser/ExpressionResultTest.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
use PHPStan\ShouldNotHappenException;
88
use PHPStan\Testing\PHPStanTestCase;
99
use PHPStan\TrinaryLogic;
10+
use PHPStan\Type\ArrayType;
1011
use PHPStan\Type\IntegerType;
12+
use PHPStan\Type\MixedType;
1113
use PHPUnit\Framework\Attributes\DataProvider;
1214
use function count;
1315
use function get_class;
@@ -127,6 +129,22 @@ public static function dataIsAlwaysTerminating(): array
127129
'var_dump(exit()."a");',
128130
true,
129131
],
132+
[
133+
'array_push($arr, fn() => "exit");',
134+
false,
135+
],
136+
[
137+
'array_push($arr, function() { exit(); });',
138+
false,
139+
],
140+
[
141+
'array_push($arr, "exit");',
142+
false,
143+
],
144+
[
145+
'array_unshift($arr, "exit");',
146+
false,
147+
],
130148
];
131149
}
132150

@@ -155,7 +173,8 @@ public function testIsAlwaysTerminating(
155173
/** @var ScopeFactory $scopeFactory */
156174
$scopeFactory = self::getContainer()->getByType(ScopeFactory::class);
157175
$scope = $scopeFactory->create(ScopeContext::create('test.php'))
158-
->assignVariable('x', new IntegerType(), new IntegerType(), TrinaryLogic::createYes());
176+
->assignVariable('x', new IntegerType(), new IntegerType(), TrinaryLogic::createYes())
177+
->assignVariable('arr', new ArrayType(new MixedType(), new MixedType()), new ArrayType(new MixedType(), new MixedType()), TrinaryLogic::createYes());
159178

160179
$result = $nodeScopeResolver->processExprNode(
161180
$stmt,

0 commit comments

Comments
 (0)