From 793481a868c88181fc6e0b831bc8f0da0e5e41eb Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 16 Oct 2025 07:08:25 +0200 Subject: [PATCH 01/12] Fix too wide bool in trivial methods --- src/Rules/TooWideTypehints/TooWideTypeCheck.php | 3 +++ .../TooWideFunctionReturnTypehintRuleTest.php | 12 ------------ .../TooWideMethodReturnTypehintRuleTest.php | 16 ---------------- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/src/Rules/TooWideTypehints/TooWideTypeCheck.php b/src/Rules/TooWideTypehints/TooWideTypeCheck.php index 5d5431a964..04289f8a5c 100644 --- a/src/Rules/TooWideTypehints/TooWideTypeCheck.php +++ b/src/Rules/TooWideTypehints/TooWideTypeCheck.php @@ -176,6 +176,9 @@ public function checkFunctionReturnType( if (count($returnStatements) === 0) { return []; } + if (count($returnStatements) === 1 && $nativeFunctionReturnType->isBoolean()->yes()) { + return []; + } $returnTypes = []; foreach ($returnStatements as $returnStatement) { diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index 992e3182e4..1e67d67656 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -78,18 +78,6 @@ public function testBug13384cPhp82(): void $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ - [ - 'Function Bug13384c\doFoo() never returns true so the return type can be changed to false.', - 5, - ], - [ - 'Function Bug13384c\doFoo2() never returns false so the return type can be changed to true.', - 9, - ], - [ - 'Function Bug13384c\doFooPhpdoc() never returns false so the return type can be changed to true.', - 93, - ], [ 'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.', 100, diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php index 0cb376aebc..bf8eba29b7 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php @@ -231,26 +231,10 @@ public function testBug13384c(): void $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ - [ - 'Method Bug13384c\Bug13384c::doBar() never returns true so the return type can be changed to false.', - 33, - ], - [ - 'Method Bug13384c\Bug13384c::doBar2() never returns false so the return type can be changed to true.', - 37, - ], [ 'Method Bug13384c\Bug13384c::doBarPhpdoc() never returns false so the return type can be changed to true.', 55, ], - [ - 'Method Bug13384c\Bug13384Static::doBar() never returns true so the return type can be changed to false.', - 62, - ], - [ - 'Method Bug13384c\Bug13384Static::doBar2() never returns false so the return type can be changed to true.', - 66, - ], [ 'Method Bug13384c\Bug13384Static::doBarPhpdoc() never returns false so the return type can be changed to true.', 84, From 7fdcec156138a0571e4de05ea5309cadc065968b Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 16 Oct 2025 07:17:50 +0200 Subject: [PATCH 02/12] ignore also bool phpdoc --- .../TooWideTypehints/TooWideTypeCheck.php | 8 +++++- .../Analyser/AnalyserIntegrationTest.php | 26 +++++++------------ .../TooWideFunctionReturnTypehintRuleTest.php | 7 +---- .../TooWideMethodReturnTypehintRuleTest.php | 11 +------- 4 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/Rules/TooWideTypehints/TooWideTypeCheck.php b/src/Rules/TooWideTypehints/TooWideTypeCheck.php index 04289f8a5c..bbb8048771 100644 --- a/src/Rules/TooWideTypehints/TooWideTypeCheck.php +++ b/src/Rules/TooWideTypehints/TooWideTypeCheck.php @@ -176,7 +176,13 @@ public function checkFunctionReturnType( if (count($returnStatements) === 0) { return []; } - if (count($returnStatements) === 1 && $nativeFunctionReturnType->isBoolean()->yes()) { + if ( + count($returnStatements) === 1 + && ( + $nativeFunctionReturnType->isBoolean()->yes() + || $phpDocFunctionReturnType->isBoolean()->yes() + ) + ) { return []; } diff --git a/tests/PHPStan/Analyser/AnalyserIntegrationTest.php b/tests/PHPStan/Analyser/AnalyserIntegrationTest.php index 9ffbc19566..c99fcbb895 100644 --- a/tests/PHPStan/Analyser/AnalyserIntegrationTest.php +++ b/tests/PHPStan/Analyser/AnalyserIntegrationTest.php @@ -1107,23 +1107,15 @@ public function testBug8376(): void public function testAssertDocblock(): void { $errors = $this->runAnalyse(__DIR__ . '/nsrt/assert-docblock.php'); - $this->assertCount(8, $errors); - $this->assertSame('Function AssertDocblock\validateStringArrayIfTrue() never returns false so the return type can be changed to true.', $errors[0]->getMessage()); - $this->assertSame(17, $errors[0]->getLine()); - $this->assertSame('Function AssertDocblock\validateStringArrayIfFalse() never returns true so the return type can be changed to false.', $errors[1]->getMessage()); - $this->assertSame(25, $errors[1]->getLine()); - $this->assertSame('Function AssertDocblock\validateStringOrIntArray() never returns true so the return type can be changed to false.', $errors[2]->getMessage()); - $this->assertSame(34, $errors[2]->getLine()); - $this->assertSame('Function AssertDocblock\validateStringOrNonEmptyIntArray() never returns true so the return type can be changed to false.', $errors[3]->getMessage()); - $this->assertSame(44, $errors[3]->getLine()); - $this->assertSame('Call to method AssertDocblock\A::testInt() with string will always evaluate to false.', $errors[4]->getMessage()); - $this->assertSame(218, $errors[4]->getLine()); - $this->assertSame('Call to method AssertDocblock\A::testNotInt() with string will always evaluate to true.', $errors[5]->getMessage()); - $this->assertSame(224, $errors[5]->getLine()); - $this->assertSame('Call to method AssertDocblock\A::testInt() with int will always evaluate to true.', $errors[6]->getMessage()); - $this->assertSame(232, $errors[6]->getLine()); - $this->assertSame('Call to method AssertDocblock\A::testNotInt() with int will always evaluate to false.', $errors[7]->getMessage()); - $this->assertSame(238, $errors[7]->getLine()); + $this->assertCount(4, $errors); + $this->assertSame('Call to method AssertDocblock\A::testInt() with string will always evaluate to false.', $errors[0]->getMessage()); + $this->assertSame(218, $errors[0]->getLine()); + $this->assertSame('Call to method AssertDocblock\A::testNotInt() with string will always evaluate to true.', $errors[1]->getMessage()); + $this->assertSame(224, $errors[1]->getLine()); + $this->assertSame('Call to method AssertDocblock\A::testInt() with int will always evaluate to true.', $errors[2]->getMessage()); + $this->assertSame(232, $errors[2]->getLine()); + $this->assertSame('Call to method AssertDocblock\A::testNotInt() with int will always evaluate to false.', $errors[3]->getMessage()); + $this->assertSame(238, $errors[3]->getLine()); } #[RequiresPhp('>= 8.0')] diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index 1e67d67656..ee2218b37e 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -77,12 +77,7 @@ public function testBug13384cPhp82(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ - [ - 'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.', - 100, - ], - ]); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); } #[RequiresPhp('< 8.2')] diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php index bf8eba29b7..6dde015a48 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php @@ -230,16 +230,7 @@ public function testBug13384c(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ - [ - 'Method Bug13384c\Bug13384c::doBarPhpdoc() never returns false so the return type can be changed to true.', - 55, - ], - [ - 'Method Bug13384c\Bug13384Static::doBarPhpdoc() never returns false so the return type can be changed to true.', - 84, - ], - ]); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); } #[RequiresPhp('< 8.2')] From d7974e77b9a009d8ffc77e1926cccca689ddf5b2 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 16 Oct 2025 13:05:57 +0200 Subject: [PATCH 03/12] for literal return true and return false, not for return $this->foo->doFoo() --- .../TooWideTypehints/TooWideTypeCheck.php | 35 ++++++++++++++----- .../TooWideFunctionReturnTypehintRuleTest.php | 7 +++- .../TooWideTypehints/data/bug-13384c.php | 8 +++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/Rules/TooWideTypehints/TooWideTypeCheck.php b/src/Rules/TooWideTypehints/TooWideTypeCheck.php index bbb8048771..9a80ed6d3f 100644 --- a/src/Rules/TooWideTypehints/TooWideTypeCheck.php +++ b/src/Rules/TooWideTypehints/TooWideTypeCheck.php @@ -2,6 +2,7 @@ namespace PHPStan\Rules\TooWideTypehints; +use PhpParser\Node\Expr\ConstFetch; use PHPStan\Analyser\Scope; use PHPStan\DependencyInjection\AutowiredParameter; use PHPStan\DependencyInjection\AutowiredService; @@ -13,6 +14,7 @@ use PHPStan\Rules\IdentifierRuleError; use PHPStan\Rules\Properties\PropertyReflectionFinder; use PHPStan\Rules\RuleErrorBuilder; +use PHPStan\TrinaryLogic; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\MixedType; use PHPStan\Type\NullType; @@ -25,8 +27,10 @@ use PHPStan\Type\VerbosityLevel; use PHPStan\Type\VoidType; use function count; +use function in_array; use function lcfirst; use function sprintf; +use function strtolower; #[AutowiredService] final class TooWideTypeCheck @@ -176,17 +180,9 @@ public function checkFunctionReturnType( if (count($returnStatements) === 0) { return []; } - if ( - count($returnStatements) === 1 - && ( - $nativeFunctionReturnType->isBoolean()->yes() - || $phpDocFunctionReturnType->isBoolean()->yes() - ) - ) { - return []; - } $returnTypes = []; + $returnsLiteralTrueFalse = []; foreach ($returnStatements as $returnStatement) { $returnNode = $returnStatement->getReturnNode(); if ($returnNode->expr === null) { @@ -194,6 +190,15 @@ public function checkFunctionReturnType( continue; } + if ( + $returnNode->expr instanceof ConstFetch + && in_array(strtolower($returnNode->expr->name->toString()), ['true', 'false'], true) + ) { + $returnsLiteralTrueFalse[] = TrinaryLogic::createYes(); + } else { + $returnsLiteralTrueFalse[] = TrinaryLogic::createNo(); + } + $returnTypes[] = $returnStatement->getScope()->getType($returnNode->expr); } @@ -214,6 +219,18 @@ public function checkFunctionReturnType( $returnType = TypeCombinator::union(...$returnTypes); + if ( + count($returnStatements) === 1 + && $returnsLiteralTrueFalse !== [] + && TrinaryLogic::extremeIdentity(...$returnsLiteralTrueFalse)->yes() + && ( + $nativeFunctionReturnType->isBoolean()->yes() + || $phpDocFunctionReturnType->isBoolean()->yes() + ) + ) { + return []; + } + $unionMessagePattern = sprintf('%s never returns %%s so it can be removed from the return type.', $functionDescription); $boolMessagePattern = sprintf('%s never returns %%s so the return type can be changed to %%s.', $functionDescription); diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index ee2218b37e..d8f6909bef 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -77,7 +77,12 @@ public function testBug13384cPhp82(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ + [ + 'Function Bug13384c\callsReturnsTrue() never returns false so the return type can be changed to true.', + 112, + ], + ]); } #[RequiresPhp('< 8.2')] diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php index 0d0ad4efbf..2038128f78 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php @@ -104,3 +104,11 @@ function doFooPhpdoc2() { function doFooMixed() { return true; } + +function returnsTrue(): true { + return true; +} + +function callsReturnsTrue(): bool { + return returnsTrue(); +} From 7cd7ecfd751a391fc163a913a075469956a21b9d Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 16 Oct 2025 13:09:36 +0200 Subject: [PATCH 04/12] fix php < 8.2 --- .../TooWideFunctionReturnTypehintRuleTest.php | 13 ++----------- .../Rules/TooWideTypehints/data/bug-13384c.php | 5 ++++- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index d8f6909bef..55889d7777 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -80,7 +80,7 @@ public function testBug13384cPhp82(): void $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ [ 'Function Bug13384c\callsReturnsTrue() never returns false so the return type can be changed to true.', - 112, + 115, ], ]); } @@ -90,16 +90,7 @@ public function testBug13384cPrePhp82(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ - [ - 'Function Bug13384c\doFooPhpdoc() never returns false so the return type can be changed to true.', - 93, - ], - [ - 'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.', - 100, - ], - ]); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); } public function testBug13384cOff(): void diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php index 2038128f78..a275fb37f5 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php @@ -105,7 +105,10 @@ function doFooMixed() { return true; } -function returnsTrue(): true { +/** + * @return true + */ +function returnsTrue(): bool { return true; } From 78ae454e381b228847c6dfeb89f87f4380092ef8 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 16 Oct 2025 13:12:21 +0200 Subject: [PATCH 05/12] simplify --- src/Rules/TooWideTypehints/TooWideTypeCheck.php | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Rules/TooWideTypehints/TooWideTypeCheck.php b/src/Rules/TooWideTypehints/TooWideTypeCheck.php index 9a80ed6d3f..2c54660117 100644 --- a/src/Rules/TooWideTypehints/TooWideTypeCheck.php +++ b/src/Rules/TooWideTypehints/TooWideTypeCheck.php @@ -182,7 +182,6 @@ public function checkFunctionReturnType( } $returnTypes = []; - $returnsLiteralTrueFalse = []; foreach ($returnStatements as $returnStatement) { $returnNode = $returnStatement->getReturnNode(); if ($returnNode->expr === null) { @@ -190,15 +189,6 @@ public function checkFunctionReturnType( continue; } - if ( - $returnNode->expr instanceof ConstFetch - && in_array(strtolower($returnNode->expr->name->toString()), ['true', 'false'], true) - ) { - $returnsLiteralTrueFalse[] = TrinaryLogic::createYes(); - } else { - $returnsLiteralTrueFalse[] = TrinaryLogic::createNo(); - } - $returnTypes[] = $returnStatement->getScope()->getType($returnNode->expr); } @@ -221,8 +211,8 @@ public function checkFunctionReturnType( if ( count($returnStatements) === 1 - && $returnsLiteralTrueFalse !== [] - && TrinaryLogic::extremeIdentity(...$returnsLiteralTrueFalse)->yes() + && $returnStatements[0]->getReturnNode()->expr instanceof ConstFetch + && in_array(strtolower($returnStatements[0]->getReturnNode()->expr->name->toString()), ['true', 'false'], true) && ( $nativeFunctionReturnType->isBoolean()->yes() || $phpDocFunctionReturnType->isBoolean()->yes() From 1e5af699ea635f4ba73543e3f14bd59a90bffda7 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 16 Oct 2025 13:13:39 +0200 Subject: [PATCH 06/12] cs --- src/Rules/TooWideTypehints/TooWideTypeCheck.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Rules/TooWideTypehints/TooWideTypeCheck.php b/src/Rules/TooWideTypehints/TooWideTypeCheck.php index 2c54660117..307a3ec528 100644 --- a/src/Rules/TooWideTypehints/TooWideTypeCheck.php +++ b/src/Rules/TooWideTypehints/TooWideTypeCheck.php @@ -14,7 +14,6 @@ use PHPStan\Rules\IdentifierRuleError; use PHPStan\Rules\Properties\PropertyReflectionFinder; use PHPStan\Rules\RuleErrorBuilder; -use PHPStan\TrinaryLogic; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\MixedType; use PHPStan\Type\NullType; From 2533d1efe130fe9486d90cdd7c9dc924be50f699 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 16 Oct 2025 13:16:26 +0200 Subject: [PATCH 07/12] fix --- .../TooWideMethodReturnTypehintRuleTest.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php index 6dde015a48..df414a8f88 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php @@ -238,16 +238,7 @@ public function testBug13384cPrePhp82(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ - [ - 'Method Bug13384c\Bug13384c::doBarPhpdoc() never returns false so the return type can be changed to true.', - 55, - ], - [ - 'Method Bug13384c\Bug13384Static::doBarPhpdoc() never returns false so the return type can be changed to true.', - 84, - ], - ]); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); } public function testBug13384cOff(): void From 244c27fb4e6f65686988f41fb45b55229242f962 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 17 Oct 2025 18:02:32 +0200 Subject: [PATCH 08/12] Discard changes to tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php --- .../TooWideFunctionReturnTypehintRuleTest.php | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index 55889d7777..992e3182e4 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -79,8 +79,20 @@ public function testBug13384cPhp82(): void $this->reportNestedTooWideType = true; $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ [ - 'Function Bug13384c\callsReturnsTrue() never returns false so the return type can be changed to true.', - 115, + 'Function Bug13384c\doFoo() never returns true so the return type can be changed to false.', + 5, + ], + [ + 'Function Bug13384c\doFoo2() never returns false so the return type can be changed to true.', + 9, + ], + [ + 'Function Bug13384c\doFooPhpdoc() never returns false so the return type can be changed to true.', + 93, + ], + [ + 'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.', + 100, ], ]); } @@ -90,7 +102,16 @@ public function testBug13384cPrePhp82(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ + [ + 'Function Bug13384c\doFooPhpdoc() never returns false so the return type can be changed to true.', + 93, + ], + [ + 'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.', + 100, + ], + ]); } public function testBug13384cOff(): void From 6409023a826d183c94f62dbddb4ac53b29b12242 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 17 Oct 2025 18:02:45 +0200 Subject: [PATCH 09/12] Discard changes to tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php --- .../TooWideMethodReturnTypehintRuleTest.php | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php index df414a8f88..0cb376aebc 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php @@ -230,7 +230,32 @@ public function testBug13384c(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ + [ + 'Method Bug13384c\Bug13384c::doBar() never returns true so the return type can be changed to false.', + 33, + ], + [ + 'Method Bug13384c\Bug13384c::doBar2() never returns false so the return type can be changed to true.', + 37, + ], + [ + 'Method Bug13384c\Bug13384c::doBarPhpdoc() never returns false so the return type can be changed to true.', + 55, + ], + [ + 'Method Bug13384c\Bug13384Static::doBar() never returns true so the return type can be changed to false.', + 62, + ], + [ + 'Method Bug13384c\Bug13384Static::doBar2() never returns false so the return type can be changed to true.', + 66, + ], + [ + 'Method Bug13384c\Bug13384Static::doBarPhpdoc() never returns false so the return type can be changed to true.', + 84, + ], + ]); } #[RequiresPhp('< 8.2')] @@ -238,7 +263,16 @@ public function testBug13384cPrePhp82(): void { $this->reportTooWideBool = true; $this->reportNestedTooWideType = true; - $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ + [ + 'Method Bug13384c\Bug13384c::doBarPhpdoc() never returns false so the return type can be changed to true.', + 55, + ], + [ + 'Method Bug13384c\Bug13384Static::doBarPhpdoc() never returns false so the return type can be changed to true.', + 84, + ], + ]); } public function testBug13384cOff(): void From c90bb0e4fe05100c9fedc984de688efbf78f9848 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 17 Oct 2025 18:06:51 +0200 Subject: [PATCH 10/12] adjust tests --- .../TooWideTypehints/data/bug-13384c.php | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php index a275fb37f5..d8989e3e9d 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php @@ -3,11 +3,11 @@ namespace Bug13384c; function doFoo(): bool { - return false; + return returnsFalse(); } function doFoo2(): bool { - return true; + return returnsTrue(); } function doFoo3(): bool { @@ -20,22 +20,22 @@ function doFoo3(): bool { class Bug13384c { public function doBarPublic(): bool { - return false; + return returnsFalse(); } /** * @return false */ private function doBarPhpdocReturn(): bool { - return false; + return returnsFalse(); } private function doBar(): bool { - return false; + return returnsFalse(); } private function doBar2(): bool { - return true; + return returnsTrue(); } private function doBar3(): bool { @@ -46,25 +46,25 @@ private function doBar3(): bool { } private function doBarMixed() { - return true; + return returnsTrue(); } /** * @return bool */ private function doBarPhpdoc() { - return true; + return returnsTrue(); } } class Bug13384Static { private static function doBar(): bool { - return false; + return returnsFalse(); } private static function doBar2(): bool { - return true; + return returnsTrue(); } private static function doBar3(): bool { @@ -75,14 +75,14 @@ private static function doBar3(): bool { } private static function doBarMixed() { - return true; + return returnsTrue(); } /** * @return bool */ private static function doBarPhpdoc() { - return true; + return returnsTrue(); } } @@ -91,18 +91,18 @@ private static function doBarPhpdoc() { * @return bool */ function doFooPhpdoc() { - return true; + return returnsTrue(); } /** * @return bool */ function doFooPhpdoc2() { - return false; + return returnsFalse(); } function doFooMixed() { - return true; + return returnsTrue(); } /** @@ -112,6 +112,17 @@ function returnsTrue(): bool { return true; } -function callsReturnsTrue(): bool { - return returnsTrue(); +/** + * @return false + */ +function returnsFalse(): bool { + return false; +} + +function returnsTrueNoPhpdoc(): bool { + return true; +} + +function returnsFalseNoPhpdoc(): bool { + return false; } From f764dd1375860e5490c7d2107e80ce9dd758cd58 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 5 Dec 2025 10:50:22 +0100 Subject: [PATCH 11/12] kill mutants --- .../TooWideFunctionReturnTypehintRuleTest.php | 19 ++++++++++++++++++- .../TooWideTypehints/data/bug-13384c.php | 11 +++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index 992e3182e4..eb68cad7eb 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -94,6 +94,14 @@ public function testBug13384cPhp82(): void 'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.', 100, ], + [ + 'Function Bug13384c\returnsTrueUnionReturn() never returns int so it can be removed from the return type.', + 130, + ], + [ + 'Function Bug13384c\returnsTruePhpdocUnionReturn() never returns int so it can be removed from the return type.', + 137, + ], ]); } @@ -116,7 +124,16 @@ public function testBug13384cPrePhp82(): void public function testBug13384cOff(): void { - $this->analyse([__DIR__ . '/data/bug-13384c.php'], []); + $this->analyse([__DIR__ . '/data/bug-13384c.php'], [ + [ + 'Function Bug13384c\returnsTrueUnionReturn() never returns int so it can be removed from the return type.', + 130, + ], + [ + 'Function Bug13384c\returnsTruePhpdocUnionReturn() never returns int so it can be removed from the return type.', + 137, + ], + ]); } public function testNestedTooWideType(): void diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php index d8989e3e9d..816a9d6dea 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php @@ -126,3 +126,14 @@ function returnsTrueNoPhpdoc(): bool { function returnsFalseNoPhpdoc(): bool { return false; } + +function returnsTrueUnionReturn(): int|bool { + return true; +} + +/** + * @return int|bool + */ +function returnsTruePhpdocUnionReturn() { + return true; +} From 5fe0dbeb7e7b3d169349de3d27308795d18691e1 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Fri, 5 Dec 2025 10:54:16 +0100 Subject: [PATCH 12/12] fix php7 --- .../TooWideFunctionReturnTypehintRuleTest.php | 8 ++++++++ tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index eb68cad7eb..a5241c9f9f 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -119,6 +119,14 @@ public function testBug13384cPrePhp82(): void 'Function Bug13384c\doFooPhpdoc2() never returns true so the return type can be changed to false.', 100, ], + [ + 'Function Bug13384c\returnsTrueUnionReturn() never returns int so it can be removed from the return type.', + 130, + ], + [ + 'Function Bug13384c\returnsTruePhpdocUnionReturn() never returns int so it can be removed from the return type.', + 137, + ], ]); } diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php index 816a9d6dea..958a3b96cb 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-13384c.php @@ -1,4 +1,4 @@ -= 8.0 namespace Bug13384c;