From a0c2e42e9fcd0c8242749a1cd986af6722f36da8 Mon Sep 17 00:00:00 2001 From: ondrejmirtes <104888+ondrejmirtes@users.noreply.github.com> Date: Fri, 6 Nov 2026 17:42:27 +0000 Subject: [PATCH 1/2] Update BetterReflection --- composer.json | 2 +- composer.lock | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index 0ea0f492b69..61ebbebd707 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "nette/utils": "^3.2.5", "nikic/php-parser": "^5.9.0", "ondram/ci-detector": "^4.0", - "ondrejmirtes/better-reflection": "6.75.0.4", + "ondrejmirtes/better-reflection": "6.75.0.5", "ondrejmirtes/composer-attribute-collector": "^1.4.0", "ondrejmirtes/phplrt-runtime": "4.2.4.1", "phpstan/php-8-stubs": "0.4.43", diff --git a/composer.lock b/composer.lock index 091fa16374a..f904781580d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4cc7fc2073c958775f1e0a26e2f33eef", + "content-hash": "5534d772515b2aa9500017806bdd1540", "packages": [ { "name": "clue/ndjson-react", @@ -1345,16 +1345,16 @@ }, { "name": "ondrejmirtes/better-reflection", - "version": "6.75.0.4", + "version": "6.75.0.5", "source": { "type": "git", "url": "https://github.com/ondrejmirtes/BetterReflection.git", - "reference": "47a79d87807e12860c3f1cafcae5f7380e4539c9" + "reference": "55cdc14744503b2ebd5ca313b26673562b07e8e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ondrejmirtes/BetterReflection/zipball/47a79d87807e12860c3f1cafcae5f7380e4539c9", - "reference": "47a79d87807e12860c3f1cafcae5f7380e4539c9", + "url": "https://api.github.com/repos/ondrejmirtes/BetterReflection/zipball/55cdc14744503b2ebd5ca313b26673562b07e8e3", + "reference": "55cdc14744503b2ebd5ca313b26673562b07e8e3", "shasum": "" }, "require": { @@ -1410,9 +1410,10 @@ ], "description": "Better Reflection - an improved code reflection API", "support": { - "source": "https://github.com/ondrejmirtes/BetterReflection/tree/6.75.0.4" + "source": "https://github.com/ondrejmirtes/BetterReflection/tree/6.75.0.5" }, - "time": "2026-10-26T21:37:39+00:00" + "time": "2026-11-06T17:40:58+00:00", + "published-time": "2026-11-06T17:41:58+00:00" }, { "name": "ondrejmirtes/composer-attribute-collector", From 4a6c3872843685be9582852d7512b2b4150995b5 Mon Sep 17 00:00:00 2001 From: "ondrej@mirtes.cz" Date: Fri, 6 Nov 2026 17:47:52 +0000 Subject: [PATCH 2/2] Skip only built-in overridden methods with a tentative return type before PHP 8.1 BetterReflection now reports tentative return types for PHP versions below 8.1 too. A method overriding a userland method whose real prototype is built-in with a tentative return type must still be checked against the userland method's return type. Amp-Thread-ID: https://ampcode.com/threads/T-01a1b1b9-0a7d-772a-a8bb-331fd76aa9cc --- src/Rules/Methods/OverridingMethodRule.php | 6 +++++- .../Rules/Methods/OverridingMethodRuleTest.php | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Rules/Methods/OverridingMethodRule.php b/src/Rules/Methods/OverridingMethodRule.php index 698cba9e755..a0156ce844d 100644 --- a/src/Rules/Methods/OverridingMethodRule.php +++ b/src/Rules/Methods/OverridingMethodRule.php @@ -274,7 +274,11 @@ public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataE $reportReturnType = !$realPrototype instanceof MethodPrototypeReflection || $realPrototype->getTentativeReturnType() === null || (is_bool($prototype->isBuiltin()) ? !$prototype->isBuiltin() : $prototype->isBuiltin()->no()); - } elseif ($realPrototype instanceof MethodPrototypeReflection && $realPrototype->getTentativeReturnType() !== null) { + } elseif ( + $realPrototype instanceof MethodPrototypeReflection + && $realPrototype->getTentativeReturnType() !== null + && $prototypeDeclaringClass->isBuiltin() + ) { // return types that are only tentative are not checked before PHP 8.1 $reportReturnType = false; } else { diff --git a/tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php b/tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php index 5d07a7b42e4..9a441ef6b28 100644 --- a/tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php +++ b/tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php @@ -654,9 +654,19 @@ public function testBug9135(): void ]); } - public function testBug10101(): void + public static function dataBug10101(): array { - $this->phpVersionId = PHP_VERSION_ID; + return [ + [70400], + [80000], + [PHP_VERSION_ID], + ]; + } + + #[DataProvider('dataBug10101')] + public function testBug10101(int $phpVersionId): void + { + $this->phpVersionId = $phpVersionId; $this->analyse([__DIR__ . '/data/bug-10101.php'], [ [ 'Return type mixed of method Bug10101\B::next() is not covariant with return type void of method Bug10101\A::next().',