diff --git a/src/Rules/Comparison/WhileLoopAlwaysTrueConditionRule.php b/src/Rules/Comparison/WhileLoopAlwaysTrueConditionRule.php index 86d0f01f2c..3f251f8366 100644 --- a/src/Rules/Comparison/WhileLoopAlwaysTrueConditionRule.php +++ b/src/Rules/Comparison/WhileLoopAlwaysTrueConditionRule.php @@ -13,6 +13,7 @@ use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\Constant\ConstantBooleanType; +use PHPStan\Type\NeverType; /** * @implements Rule @@ -67,6 +68,12 @@ public function processNode( $originalNode = $node->getOriginalNode(); $exprType = $this->helper->getBooleanType($scope, $originalNode->cond); if ($exprType->isTrue()->yes()) { + $ref = $scope->getFunction() ?? $scope->getAnonymousFunctionReflection(); + + if ($ref !== null && $ref->getReturnType() instanceof NeverType) { + return []; + } + $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $originalNode): RuleErrorBuilder { if (!$this->treatPhpDocTypesAsCertain) { return $ruleErrorBuilder; diff --git a/tests/PHPStan/Rules/Comparison/WhileLoopAlwaysTrueConditionRuleTest.php b/tests/PHPStan/Rules/Comparison/WhileLoopAlwaysTrueConditionRuleTest.php index 45bcf32a83..b0fe019bd4 100644 --- a/tests/PHPStan/Rules/Comparison/WhileLoopAlwaysTrueConditionRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/WhileLoopAlwaysTrueConditionRuleTest.php @@ -4,6 +4,7 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +use PHPUnit\Framework\Attributes\RequiresPhp; /** * @extends RuleTestCase @@ -47,4 +48,10 @@ public function testRule(): void ]); } + #[RequiresPhp('>= 8.1')] + public function testRulePHP81(): void + { + $this->analyse([__DIR__ . '/data/while-loop-true-php81.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/while-loop-true-php81.php b/tests/PHPStan/Rules/Comparison/data/while-loop-true-php81.php new file mode 100644 index 0000000000..c35a3d9d57 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/while-loop-true-php81.php @@ -0,0 +1,21 @@ +