diff --git a/tests/PHPStan/Analyser/nsrt/bug-5207b.php b/tests/PHPStan/Analyser/nsrt/bug-5207b.php new file mode 100644 index 00000000000..76d3fec935b --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-5207b.php @@ -0,0 +1,38 @@ += 8.0 + +declare(strict_types = 1); + +namespace Bug5207b; + +use function PHPStan\Testing\assertType; + +abstract class HelloWorld { + abstract public function getChild(): ?HelloWorld; + + public function sayHello(): void { + $foo = null !== $this->getChild()->getChild(); + if ($foo) { + assertType('Bug5207b\HelloWorld|null', $this->getChild()); // could be Bug5207b\HelloWorld + assertType('Bug5207b\HelloWorld', $this->getChild()->getChild()); + assertType('Bug5207b\HelloWorld|null', $this->getChild()->getChild()->getChild()); + } + } + + public function sayFoo(): void { + $foo = null !== $this?->getChild()?->getChild(); + if ($foo) { + assertType('Bug5207b\HelloWorld', $this->getChild()); + assertType('Bug5207b\HelloWorld', $this->getChild()->getChild()); + assertType('Bug5207b\HelloWorld|null', $this->getChild()->getChild()->getChild()); + } + } + + public function sayBar(): void { + $foo = null !== $this?->getChild()->getChild(); + if ($foo) { + assertType('Bug5207b\HelloWorld', $this->getChild()); + assertType('Bug5207b\HelloWorld', $this->getChild()->getChild()); + assertType('Bug5207b\HelloWorld|null', $this->getChild()->getChild()->getChild()); + } + } +} diff --git a/tests/PHPStan/Rules/Methods/NullsafeMethodCallRuleTest.php b/tests/PHPStan/Rules/Methods/NullsafeMethodCallRuleTest.php index 0d1bc3e1b6e..4b0b8db7e2b 100644 --- a/tests/PHPStan/Rules/Methods/NullsafeMethodCallRuleTest.php +++ b/tests/PHPStan/Rules/Methods/NullsafeMethodCallRuleTest.php @@ -74,6 +74,17 @@ public function testBug8523c(): void $this->analyse([__DIR__ . '/data/bug-8523c.php'], []); } + #[RequiresPhp('>= 8.0.0')] + public function testBug5207b(): void + { + $this->analyse([__DIR__ . '/data/bug-5207b.php'], [ + [ + 'Using nullsafe method call on non-nullable type Bug5207b\OrderCustomerEntity. Use -> instead.', + 47, + ], + ]); + } + #[RequiresPhp('>= 8.1.0')] public function testBug12222(): void { diff --git a/tests/PHPStan/Rules/Methods/data/bug-5207b.php b/tests/PHPStan/Rules/Methods/data/bug-5207b.php new file mode 100644 index 00000000000..010dae12c9c --- /dev/null +++ b/tests/PHPStan/Rules/Methods/data/bug-5207b.php @@ -0,0 +1,52 @@ += 8.0 + +declare(strict_types = 1); + +namespace Bug5207b; + +class OrderEntity +{ + public function getOrderCustomer(): ?OrderCustomerEntity + { + return new OrderCustomerEntity(); + } +} + +class OrderCustomerEntity +{ + public function getCustomer(): ?CustomerEntity + { + return null; + } + + public function getEmail(): string + { + return ''; + } +} + +class CustomerEntity +{ + public function getGuest(): bool + { + return true; + } +} + +class GuestAuthenticator +{ + public function validate(OrderEntity $order, string $s): void + { + $isOrderByGuest = $order->getOrderCustomer()?->getCustomer()?->getGuest(); + + if (!$isOrderByGuest) { + throw new \Exception(); + } + + + if (mb_strtolower($s) !== mb_strtolower($order->getOrderCustomer()?->getEmail() ?: '')) { + throw new \Exception(); + } + } +} +