Skip to content

Commit bde30fc

Browse files
committed
Assert-and-throws-are-side-effects
1 parent f9c7bbd commit bde30fc

File tree

4 files changed

+118
-1
lines changed

4 files changed

+118
-1
lines changed

Diff for: src/Rules/Pure/FunctionPurityCheck.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ public function check(
6666
))->identifier(sprintf('pure%s.parameterByRef', $identifier))->build();
6767
}
6868

69-
if ($returnType->isVoid()->yes() && !$isConstructor) {
69+
if (
70+
$returnType->isVoid()->yes()
71+
&& !$isConstructor
72+
&& $functionReflection->getThrowType() === null
73+
&& $functionReflection->getAsserts()->getAll() === []
74+
) {
7075
$errors[] = RuleErrorBuilder::message(sprintf(
7176
'%s is marked as pure but returns void.',
7277
$functionDescription,

Diff for: tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,9 @@ public function testBug11361(): void
167167
]);
168168
}
169169

170+
public function testBug12224(): void
171+
{
172+
$this->analyse([__DIR__ . '/data/bug-12224.php'], []);
173+
}
174+
170175
}

Diff for: tests/PHPStan/Rules/Pure/PureMethodRuleTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,10 @@ public function dataBug11207(): array
194194
];
195195
}
196196

197+
public function testBug12224(): void
198+
{
199+
$this->treatPhpDocTypesAsCertain = true;
200+
$this->analyse([__DIR__ . '/data/bug-12224.php'], []);
201+
}
202+
197203
}

Diff for: tests/PHPStan/Rules/Pure/data/bug-12224.php

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @phpstan-pure
5+
* @throws \Exception
6+
*/
7+
function pureWithThrows(): void
8+
{
9+
throw new \Exception();
10+
}
11+
12+
/**
13+
* @phpstan-pure
14+
* @phpstan-assert int $a
15+
*/
16+
function pureWithAssert(mixed $a): void
17+
{
18+
if (!is_int($a)) {
19+
throw new \Exception();
20+
}
21+
}
22+
23+
/**
24+
* @phpstan-pure
25+
* @phpstan-assert int $a
26+
*/
27+
function pureWithAssertAndReturn(mixed $a): int
28+
{
29+
if (!is_int($a)) {
30+
throw new \Exception();
31+
}
32+
return $a;
33+
}
34+
35+
class A {
36+
/**
37+
* @phpstan-pure
38+
* @throws \Exception
39+
*/
40+
public function pureWithThrows(): void
41+
{
42+
throw new \Exception();
43+
}
44+
45+
/**
46+
* @phpstan-pure
47+
* @phpstan-assert int $a
48+
*/
49+
public function pureWithAssert(mixed $a): void
50+
{
51+
if (!is_int($a)) {
52+
throw new \Exception();
53+
}
54+
}
55+
56+
/**
57+
* @phpstan-pure
58+
* @phpstan-assert int $a
59+
*/
60+
public function pureWithAssertAndReturn(mixed $a): int
61+
{
62+
if (!is_int($a)) {
63+
throw new \Exception();
64+
}
65+
return $a;
66+
}
67+
}
68+
69+
class B {
70+
/**
71+
* @phpstan-pure
72+
* @throws \Exception
73+
*/
74+
public static function pureWithThrows(): void
75+
{
76+
throw new \Exception();
77+
}
78+
79+
/**
80+
* @phpstan-pure
81+
* @phpstan-assert int $a
82+
*/
83+
public static function pureWithAssert(mixed $a): void
84+
{
85+
if (!is_int($a)) {
86+
throw new \Exception();
87+
}
88+
}
89+
90+
/**
91+
* @phpstan-pure
92+
* @phpstan-assert int $a
93+
*/
94+
public static function pureWithAssertAndReturn(mixed $a): int
95+
{
96+
if (!is_int($a)) {
97+
throw new \Exception();
98+
}
99+
return $a;
100+
}
101+
}

0 commit comments

Comments
 (0)