From 23f52571d172197c8abee2d29af82c4e0c8bd193 Mon Sep 17 00:00:00 2001 From: Jack Worman Date: Mon, 9 Dec 2024 22:56:34 -0500 Subject: [PATCH] Respect asserts and throws on pure functions that return void --- src/Rules/Pure/FunctionPurityCheck.php | 8 +- .../Rules/Pure/PureFunctionRuleTest.php | 10 ++ .../PHPStan/Rules/Pure/PureMethodRuleTest.php | 8 ++ tests/PHPStan/Rules/Pure/data/bug-12224.php | 91 +++++++++++++++++++ 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/Pure/data/bug-12224.php diff --git a/src/Rules/Pure/FunctionPurityCheck.php b/src/Rules/Pure/FunctionPurityCheck.php index 817b6a3273..ccc85a1c24 100644 --- a/src/Rules/Pure/FunctionPurityCheck.php +++ b/src/Rules/Pure/FunctionPurityCheck.php @@ -59,7 +59,13 @@ public function check( ))->identifier(sprintf('pure%s.parameterByRef', $identifier))->build(); } - if ($returnType->isVoid()->yes() && !$isConstructor) { + $throwType = $functionReflection->getThrowType(); + if ( + $returnType->isVoid()->yes() + && !$isConstructor + && ($throwType === null || $throwType->isVoid()->yes()) + && $functionReflection->getAsserts()->getAll() === [] + ) { $errors[] = RuleErrorBuilder::message(sprintf( '%s is marked as pure but returns void.', $functionDescription, diff --git a/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php b/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php index c310f6177c..9be4df6153 100644 --- a/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php +++ b/tests/PHPStan/Rules/Pure/PureFunctionRuleTest.php @@ -167,4 +167,14 @@ public function testBug11361(): void ]); } + public function testBug12224(): void + { + $this->analyse([__DIR__ . '/data/bug-12224.php'], [ + [ + 'Function PHPStan\Rules\Pure\data\pureWithThrowsVoid() is marked as pure but returns void.', + 18, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php b/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php index 19d1eed263..a483c6d580 100644 --- a/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php +++ b/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php @@ -212,4 +212,12 @@ public function testBug12048(): void $this->analyse([__DIR__ . '/data/bug-12048.php'], []); } + public function testBug12224(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-12224.php'], [ + ['Method PHPStan\Rules\Pure\data\A::pureWithThrowsVoid() is marked as pure but returns void.', 47], + ]); + } + } diff --git a/tests/PHPStan/Rules/Pure/data/bug-12224.php b/tests/PHPStan/Rules/Pure/data/bug-12224.php new file mode 100644 index 0000000000..b93de83178 --- /dev/null +++ b/tests/PHPStan/Rules/Pure/data/bug-12224.php @@ -0,0 +1,91 @@ +