Skip to content

Commit 31ed326

Browse files
committed
CallableTypeHelper - copy variadic parameters if the accepting closure has more parameters
1 parent 00ee5ee commit 31ed326

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

src/Type/CallableTypeHelper.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use PHPStan\Reflection\ParametersAcceptor;
66
use PHPStan\TrinaryLogic;
7+
use function array_key_exists;
78
use function array_merge;
9+
use function count;
810
use function sprintf;
911

1012
class CallableTypeHelper
@@ -19,6 +21,23 @@ public static function isParametersAcceptorSuperTypeOf(
1921
$theirParameters = $theirs->getParameters();
2022
$ourParameters = $ours->getParameters();
2123

24+
$lastParameter = null;
25+
foreach ($theirParameters as $theirParameter) {
26+
$lastParameter = $theirParameter;
27+
}
28+
if (
29+
$lastParameter !== null
30+
&& $lastParameter->isVariadic()
31+
&& count($theirParameters) < count($ourParameters)
32+
) {
33+
foreach ($ourParameters as $i => $ourParameter) {
34+
if (array_key_exists($i, $theirParameters)) {
35+
continue;
36+
}
37+
$theirParameters[] = $lastParameter;
38+
}
39+
}
40+
2241
$result = null;
2342
foreach ($theirParameters as $i => $theirParameter) {
2443
$parameterDescription = $theirParameter->getName() === '' ? sprintf('#%d', $i + 1) : sprintf('#%d $%s', $i + 1, $theirParameter->getName());

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,4 +1421,18 @@ public function testBug6175(): void
14211421
$this->analyse([__DIR__ . '/data/bug-6175.php'], []);
14221422
}
14231423

1424+
public function testBug9699(): void
1425+
{
1426+
if (PHP_VERSION_ID < 80100) {
1427+
$this->markTestSkipped('Test requires PHP 8.1');
1428+
}
1429+
1430+
$this->analyse([__DIR__ . '/data/bug-9699.php'], [
1431+
[
1432+
'Parameter #1 $f of function Bug9699\int_int_int_string expects Closure(int, int, int, string): int, Closure(int, int, int ...): int given.',
1433+
19,
1434+
],
1435+
]);
1436+
}
1437+
14241438
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php // lint >= 8.1
2+
3+
namespace Bug9699;
4+
5+
function withVariadicParam(int $a, int $b, int ...$rest): int
6+
{
7+
return array_sum([$a, $b, ...$rest]);
8+
}
9+
10+
/**
11+
* @param \Closure(int, int, int, string): int $f
12+
*/
13+
function int_int_int_string(\Closure $f): void
14+
{
15+
$f(0, 0, 0, '');
16+
}
17+
18+
// false negative: expected issue here
19+
int_int_int_string(withVariadicParam(...));

0 commit comments

Comments
 (0)