Skip to content

Commit 850d542

Browse files
committed
Test @pure-unless-parameter-passed with a variadic parameter
Cover a function whose flagged by-ref parameter is followed by a trailing variadic: omitting the parameter stays pure, passing it is impure, and the extra variadic arguments do not affect the flagged parameter.
1 parent 0766a41 commit 850d542

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

‎tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,14 @@ public function testPureUnlessParameterPassed(): void
434434
'Function PureUnlessParameterPassedFunction\nonOptionalUnlessParameterPassed() is marked @pure-unless-parameter-passed for parameter $count, but $count is not optional, so function PureUnlessParameterPassedFunction\nonOptionalUnlessParameterPassed() is never pure.',
435435
350,
436436
],
437+
[
438+
'Impure call to function PureUnlessParameterPassedFunction\myReplaceVariadic() in pure function PureUnlessParameterPassedFunction\pureVariadicPassingCount().',
439+
387,
440+
],
441+
[
442+
'Impure call to function PureUnlessParameterPassedFunction\myReplaceVariadic() in pure function PureUnlessParameterPassedFunction\pureVariadicPassingCountWithExtra().',
443+
398,
444+
],
437445
]);
438446
}
439447

‎tests/PHPStan/Rules/Pure/data/pure-unless-parameter-passed.php‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,45 @@ function nonOptionalUnlessParameterPassed(string $subject, int &$count): string
355355

356356
return $subject;
357357
}
358+
359+
/**
360+
* @param-out int $count
361+
* @pure-unless-parameter-passed $count
362+
*/
363+
function myReplaceVariadic(string $subject, int &$count = 0, string ...$extra): string
364+
{
365+
$count = 1;
366+
367+
return $subject;
368+
}
369+
370+
/**
371+
* @phpstan-pure
372+
*/
373+
function pureVariadicOmittingCount(string $s): string
374+
{
375+
// The signature has a trailing variadic, but the flagged $count is omitted, so
376+
// the call stays pure.
377+
return myReplaceVariadic($s);
378+
}
379+
380+
/**
381+
* @phpstan-pure
382+
*/
383+
function pureVariadicPassingCount(string $s): string
384+
{
385+
$count = 0;
386+
// $count is passed, so the call is impure regardless of the trailing variadic.
387+
return myReplaceVariadic($s, $count);
388+
}
389+
390+
/**
391+
* @phpstan-pure
392+
*/
393+
function pureVariadicPassingCountWithExtra(string $s): string
394+
{
395+
$count = 0;
396+
// $count is passed and the trailing variadic is also filled; the extra variadic
397+
// arguments do not affect the flagged parameter, so the call is impure.
398+
return myReplaceVariadic($s, $count, 'a', 'b');
399+
}

0 commit comments

Comments
 (0)