From 3efbe606504b2d90cf0ecd72e17ad465dfc1bf54 Mon Sep 17 00:00:00 2001 From: phpstan-bot <79867460+phpstan-bot@users.noreply.github.com> Date: Tue, 17 Feb 2026 05:02:10 +0000 Subject: [PATCH] Fix circular @phpstan-import-type between classes making aliases unresolvable - When two classes have mutual @phpstan-import-type tags (FooType imports Bar from BarType, BarType imports Foo from FooType), the circular detection in ClassReflection::getTypeAliases() was too aggressive - The fix returns local type aliases (defined via @phpstan-type) when circular import resolution is detected, since local aliases don't depend on imports - Added regression test in tests/PHPStan/Rules/PhpDoc/data/bug-11463.php Closes https://github.com/phpstan/phpstan/issues/11463 --- src/Reflection/ClassReflection.php | 7 +++++ .../PhpDoc/IncompatiblePhpDocTypeRuleTest.php | 5 ++++ tests/PHPStan/Rules/PhpDoc/data/bug-11463.php | 28 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 tests/PHPStan/Rules/PhpDoc/data/bug-11463.php diff --git a/src/Reflection/ClassReflection.php b/src/Reflection/ClassReflection.php index a8c7913674..b67064b5ec 100644 --- a/src/Reflection/ClassReflection.php +++ b/src/Reflection/ClassReflection.php @@ -1376,6 +1376,13 @@ public function getTypeAliases(): array // prevent circular imports if (array_key_exists($this->getName(), self::$resolvingTypeAliasImports)) { + // Return only local type aliases to break the cycle. + // Imported aliases are not available yet, but local ones + // don't depend on other classes and can be returned safely. + $localAliases = array_map(static fn (TypeAliasTag $typeAliasTag): TypeAlias => $typeAliasTag->getTypeAlias(), $typeAliasTags); + if ($localAliases !== []) { + return $localAliases; + } throw new CircularTypeAliasDefinitionException(); } diff --git a/tests/PHPStan/Rules/PhpDoc/IncompatiblePhpDocTypeRuleTest.php b/tests/PHPStan/Rules/PhpDoc/IncompatiblePhpDocTypeRuleTest.php index 44d03ede8a..5c2b248296 100644 --- a/tests/PHPStan/Rules/PhpDoc/IncompatiblePhpDocTypeRuleTest.php +++ b/tests/PHPStan/Rules/PhpDoc/IncompatiblePhpDocTypeRuleTest.php @@ -487,4 +487,9 @@ public function testBug9708(): void $this->analyse([__DIR__ . '/data/bug-9708.php'], []); } + public function testBug11463(): void + { + $this->analyse([__DIR__ . '/data/bug-11463.php'], []); + } + } diff --git a/tests/PHPStan/Rules/PhpDoc/data/bug-11463.php b/tests/PHPStan/Rules/PhpDoc/data/bug-11463.php new file mode 100644 index 0000000000..09235324b2 --- /dev/null +++ b/tests/PHPStan/Rules/PhpDoc/data/bug-11463.php @@ -0,0 +1,28 @@ +