From 83836553799b6594a9e0fbb8da59be343f2f8347 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Wed, 13 Aug 2025 13:03:56 +0200 Subject: [PATCH] Added regression test --- .../TooWideTypehints/TooWideTypeCheck.php | 7 +++ .../TooWideClosureReturnTypehintRuleTest.php | 5 ++ .../TooWideFunctionReturnTypehintRuleTest.php | 5 ++ .../TooWideMethodReturnTypehintRuleTest.php | 31 +++++++++--- .../Rules/TooWideTypehints/data/bug-10312.php | 48 +++++++++++++++++++ .../TooWideTypehints/data/bug-10312a.php | 45 +++++++++++++++++ .../TooWideTypehints/data/bug-10312b.php | 40 ++++++++++++++++ .../TooWideTypehints/data/bug-10312c.php | 44 +++++++++++++++++ .../TooWideTypehints/data/bug-10312d.php | 41 ++++++++++++++++ .../TooWideTypehints/data/bug-10312e.php | 44 +++++++++++++++++ 10 files changed, 304 insertions(+), 6 deletions(-) create mode 100644 tests/PHPStan/Rules/TooWideTypehints/data/bug-10312.php create mode 100644 tests/PHPStan/Rules/TooWideTypehints/data/bug-10312a.php create mode 100644 tests/PHPStan/Rules/TooWideTypehints/data/bug-10312b.php create mode 100644 tests/PHPStan/Rules/TooWideTypehints/data/bug-10312c.php create mode 100644 tests/PHPStan/Rules/TooWideTypehints/data/bug-10312d.php create mode 100644 tests/PHPStan/Rules/TooWideTypehints/data/bug-10312e.php diff --git a/src/Rules/TooWideTypehints/TooWideTypeCheck.php b/src/Rules/TooWideTypehints/TooWideTypeCheck.php index 14eff168dd..8ea9a0cea4 100644 --- a/src/Rules/TooWideTypehints/TooWideTypeCheck.php +++ b/src/Rules/TooWideTypehints/TooWideTypeCheck.php @@ -98,6 +98,13 @@ public function checkFunction( $returnType = TypeCombinator::union(...$returnTypes); + if ( + $returnType->isConstantScalarValue()->yes() + && $functionReturnType->isConstantScalarValue()->yes() + ) { + return []; + } + // Do not require to have @return null/true/false in descendant classes if ( $checkDescendantClass diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideClosureReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideClosureReturnTypehintRuleTest.php index 794fed67ae..e7dfbc6d94 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideClosureReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideClosureReturnTypehintRuleTest.php @@ -18,6 +18,11 @@ protected function getRule(): Rule ); } + public function testBug10312e(): void + { + $this->analyse([__DIR__ . '/data/bug-10312e.php'], []); + } + public function testRule(): void { $this->analyse([__DIR__ . '/data/tooWideClosureReturnType.php'], [ diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php index 36c224c65f..cce5fd6e0e 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideFunctionReturnTypehintRuleTest.php @@ -61,4 +61,9 @@ public function testBug11980(): void ]); } + public function testBug10312a(): void + { + $this->analyse([__DIR__ . '/data/bug-10312a.php'], []); + } + } diff --git a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php index 36ad02ad92..677e4570be 100644 --- a/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php +++ b/tests/PHPStan/Rules/TooWideTypehints/TooWideMethodReturnTypehintRuleTest.php @@ -88,12 +88,7 @@ public function testPublicProtectedWithInheritance(): void public function testBug5095(): void { - $this->analyse([__DIR__ . '/data/bug-5095.php'], [ - [ - 'Method Bug5095\Parser::unaryOperatorFor() never returns \'not\' so it can be removed from the return type.', - 21, - ], - ]); + $this->analyse([__DIR__ . '/data/bug-5095.php'], []); } #[RequiresPhp('>= 8.0')] @@ -199,4 +194,28 @@ public function testBug11980(): void ]); } + public function testBug10312(): void + { + $this->checkProtectedAndPublicMethods = true; + $this->analyse([__DIR__ . '/data/bug-10312.php'], []); + } + + public function testBug10312b(): void + { + $this->checkProtectedAndPublicMethods = true; + $this->analyse([__DIR__ . '/data/bug-10312b.php'], []); + } + + public function testBug10312c(): void + { + $this->checkProtectedAndPublicMethods = true; + $this->analyse([__DIR__ . '/data/bug-10312c.php'], []); + } + + public function testBug10312d(): void + { + $this->checkProtectedAndPublicMethods = true; + $this->analyse([__DIR__ . '/data/bug-10312d.php'], []); + } + } diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312.php new file mode 100644 index 0000000000..d2c2aed1a1 --- /dev/null +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312.php @@ -0,0 +1,48 @@ += 8.1 + +declare(strict_types = 1); + +namespace Bug10312c; + +enum Foo: int +{ + case BAR = 1; + case BAZ = 2; +} + +interface ReturnsFoo +{ + /** @return value-of */ + public function returnsFooValue(): int; +} + +class ReturnsBar implements ReturnsFoo +{ + #[\Override] + public function returnsFooValue(): int + { + return Foo::BAR->value; + } +} + +class ReturnsBarWithFinalMethod implements ReturnsFoo +{ + #[\Override] + final public function returnsFooValue(): int + { + return Foo::BAR->value; + } +} + +final class ReturnsBaz implements ReturnsFoo +{ + #[\Override] + public function returnsFooValue(): int + { + return Foo::BAZ->value; + } +} diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312d.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312d.php new file mode 100644 index 0000000000..41f463d27b --- /dev/null +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312d.php @@ -0,0 +1,41 @@ += 8.1 + +declare(strict_types = 1); + +namespace Bug10312d; + +enum Foo: int +{ + case BAR = 1; + case BAZ = 2; +} + +class FooBar { + public ?Foo $foo = null; +} + +interface ReturnsFoo +{ + /** @return value-of */ + public function returnsFooValue(): int; + + /** @return value-of|null */ + public function returnsFooOrNullValue(): ?int; +} + +final class ReturnsNullsafeBaz implements ReturnsFoo +{ + #[\Override] + public function returnsFooValue(): int + { + $f = new FooBar(); + return $f->foo?->value; + } + + #[\Override] + public function returnsFooOrNullValue(): ?int + { + $f = new FooBar(); + return $f->foo?->value; + } +} diff --git a/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312e.php b/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312e.php new file mode 100644 index 0000000000..c7907aae14 --- /dev/null +++ b/tests/PHPStan/Rules/TooWideTypehints/data/bug-10312e.php @@ -0,0 +1,44 @@ +