Skip to content

Commit f1abacd

Browse files
committed
Closure with by-ref parameter is impure
1 parent fc75deb commit f1abacd

File tree

5 files changed

+58
-0
lines changed

5 files changed

+58
-0
lines changed

src/Analyser/MutatingScope.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,20 @@ static function (Node $node, Scope $scope) use ($arrowScope, &$arrowFunctionImpu
15271527
}
15281528
}
15291529

1530+
foreach ($parameters as $parameter) {
1531+
if ($parameter->passedByReference()->no()) {
1532+
continue;
1533+
}
1534+
1535+
$impurePoints[] = new ImpurePoint(
1536+
$this,
1537+
$node,
1538+
'functionCall',
1539+
'call to a Closure with by-ref parameter',
1540+
true,
1541+
);
1542+
}
1543+
15301544
$throwPointsForClosureType = array_map(static fn (ThrowPoint $throwPoint) => $throwPoint->isExplicit() ? SimpleThrowPoint::createExplicit($throwPoint->getType(), $throwPoint->canContainAnyThrowable()) : SimpleThrowPoint::createImplicit(), $throwPoints);
15311545
$impurePointsForClosureType = array_map(static fn (ImpurePoint $impurePoint) => new SimpleImpurePoint($impurePoint->getIdentifier(), $impurePoint->getDescription(), $impurePoint->isCertain()), $impurePoints);
15321546

tests/PHPStan/Rules/DeadCode/BetterNoopRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,9 @@ public function testBug11001(): void
153153
$this->analyse([__DIR__ . '/data/bug-11001.php'], []);
154154
}
155155

156+
public function testBug11361(): void
157+
{
158+
$this->analyse([__DIR__ . '/data/bug-11361.php'], []);
159+
}
160+
156161
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Bug11361;
4+
5+
function foo(): void
6+
{
7+
$bar = function(&$var) {
8+
$var++;
9+
};
10+
$a = array(0);
11+
$bar($a[0]);
12+
}

tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,14 @@ public function testFirstClassCallable(): void
157157
]);
158158
}
159159

160+
public function testBug11361(): void
161+
{
162+
$this->analyse([__DIR__ . '/data/bug-11361-pure.php'], [
163+
[
164+
'Impure call to a Closure with by-ref parameter in pure function Bug11361Pure\foo().',
165+
14,
166+
],
167+
]);
168+
}
169+
160170
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Bug11361Pure;
4+
5+
/**
6+
* @phpstan-pure
7+
*/
8+
function foo(): int
9+
{
10+
$bar = function(&$var) {
11+
$var++;
12+
};
13+
$a = array(0);
14+
$bar($a[0]);
15+
16+
return 1;
17+
}

0 commit comments

Comments
 (0)