Skip to content

Commit

Permalink
CallableTypeHelper - copy variadic parameters if the accepting closur…
Browse files Browse the repository at this point in the history
…e has more parameters
  • Loading branch information
ondrejmirtes committed Aug 8, 2023
1 parent 00ee5ee commit 31ed326
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/Type/CallableTypeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use PHPStan\Reflection\ParametersAcceptor;
use PHPStan\TrinaryLogic;
use function array_key_exists;
use function array_merge;
use function count;
use function sprintf;

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

$lastParameter = null;
foreach ($theirParameters as $theirParameter) {
$lastParameter = $theirParameter;
}
if (
$lastParameter !== null
&& $lastParameter->isVariadic()
&& count($theirParameters) < count($ourParameters)
) {
foreach ($ourParameters as $i => $ourParameter) {
if (array_key_exists($i, $theirParameters)) {
continue;
}
$theirParameters[] = $lastParameter;
}
}

$result = null;
foreach ($theirParameters as $i => $theirParameter) {
$parameterDescription = $theirParameter->getName() === '' ? sprintf('#%d', $i + 1) : sprintf('#%d $%s', $i + 1, $theirParameter->getName());
Expand Down
14 changes: 14 additions & 0 deletions tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1421,4 +1421,18 @@ public function testBug6175(): void
$this->analyse([__DIR__ . '/data/bug-6175.php'], []);
}

public function testBug9699(): void
{
if (PHP_VERSION_ID < 80100) {
$this->markTestSkipped('Test requires PHP 8.1');
}

$this->analyse([__DIR__ . '/data/bug-9699.php'], [
[
'Parameter #1 $f of function Bug9699\int_int_int_string expects Closure(int, int, int, string): int, Closure(int, int, int ...): int given.',
19,
],
]);
}

}
19 changes: 19 additions & 0 deletions tests/PHPStan/Rules/Functions/data/bug-9699.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php // lint >= 8.1

namespace Bug9699;

function withVariadicParam(int $a, int $b, int ...$rest): int
{
return array_sum([$a, $b, ...$rest]);
}

/**
* @param \Closure(int, int, int, string): int $f
*/
function int_int_int_string(\Closure $f): void
{
$f(0, 0, 0, '');
}

// false negative: expected issue here
int_int_int_string(withVariadicParam(...));

0 comments on commit 31ed326

Please sign in to comment.