diff --git a/src/PhpDoc/TypeNodeResolver.php b/src/PhpDoc/TypeNodeResolver.php index 8af74bf9264..7a42ff77292 100644 --- a/src/PhpDoc/TypeNodeResolver.php +++ b/src/PhpDoc/TypeNodeResolver.php @@ -483,8 +483,9 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco case 'parent': if ($this->getReflectionProvider()->hasClass($nameScope->getClassName())) { $classReflection = $this->getReflectionProvider()->getClass($nameScope->getClassName()); - if ($classReflection->getParentClass() !== null) { - return new ObjectType($classReflection->getParentClass()->getName()); + $parentClass = $classReflection->getNativeReflection()->getParentClass(); + if ($parentClass !== false) { + return new ObjectType($parentClass->getName()); } } diff --git a/tests/PHPStan/Analyser/AnalyserIntegrationTest.php b/tests/PHPStan/Analyser/AnalyserIntegrationTest.php index 8a169e150e1..460810673a8 100644 --- a/tests/PHPStan/Analyser/AnalyserIntegrationTest.php +++ b/tests/PHPStan/Analyser/AnalyserIntegrationTest.php @@ -1522,6 +1522,13 @@ public function testBug8835(): void $this->assertNoErrors($errors); } + public function testBug14439(): void + { + // endless loop crash with @extends parent + $errors = $this->runAnalyse(__DIR__ . '/data/bug-14439.php'); + $this->assertNoErrors($errors); + } + /** * @param string[]|null $allAnalysedFiles * @return list diff --git a/tests/PHPStan/Analyser/data/bug-14439.php b/tests/PHPStan/Analyser/data/bug-14439.php new file mode 100644 index 00000000000..3430abbf00c --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-14439.php @@ -0,0 +1,26 @@ + + */ +abstract class AbstractFoo extends AbstractBar +{ +} + +/** + * @template T of int + * @extends parent + */ +class Foo extends AbstractFoo +{ +}