From 0523074f0dc53aee1cd246a2e36e53dc9adc7647 Mon Sep 17 00:00:00 2001 From: staabm <120441+staabm@users.noreply.github.com> Date: Tue, 23 Jun 2026 13:49:54 +0000 Subject: [PATCH] Add regression test for invariant template type narrowed by control flow in a method getter - Add tests/PHPStan/Rules/Methods/data/bug-11776.php reproducing the reported false positive where a getter returning a property typed with `class-string>` was reported as not matching its own `@return`. - Register testBug11776() in ReturnTypeRuleTest covering the method-return path of the bug fixed in TemplateTypeVariance (invariant variance no longer mismatches when both arguments are the same template parameter narrowed by control flow). - Probed analogous constructs (passing the property to a method parameter of the same narrowed template type, and assigning it to another property of the same type); neither triggers the invariant variance equality check, so they were never affected. The function-return sibling is already covered by bug-13190. --- .../Rules/Methods/ReturnTypeRuleTest.php | 6 ++++ .../PHPStan/Rules/Methods/data/bug-11776.php | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/PHPStan/Rules/Methods/data/bug-11776.php diff --git a/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php b/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php index f6196b99cab..7b26672d8bf 100644 --- a/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php +++ b/tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php @@ -1353,4 +1353,10 @@ public function testBug12110(): void $this->analyse([__DIR__ . '/data/bug-12110.php'], []); } + #[RequiresPhp('>= 8.2.0')] + public function testBug11776(): void + { + $this->analyse([__DIR__ . '/data/bug-11776.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Methods/data/bug-11776.php b/tests/PHPStan/Rules/Methods/data/bug-11776.php new file mode 100644 index 00000000000..3bfb2d091e6 --- /dev/null +++ b/tests/PHPStan/Rules/Methods/data/bug-11776.php @@ -0,0 +1,29 @@ += 8.2 + +declare(strict_types=1); + +namespace Bug11776; + +/** + * @template TOperation of int|string + */ +interface EnumAsFilterInterface {} + +/** + * @template TOperation of scalar + */ +final readonly class ScalarableChoice +{ + /** + * @param class-string> $choiceClassName + */ + public function __construct(private string $choiceClassName) {} + + /** + * @return class-string> + */ + public function getChoiceClassName(): string + { + return $this->choiceClassName; + } +}