From d395e9867ee3ef3994d5b5288751f34fdd89abf8 Mon Sep 17 00:00:00 2001 From: Philosoft Date: Fri, 7 Aug 2026 15:21:57 -0400 Subject: [PATCH 1/3] [DeadCode] Skip RemoveReturnTagIncompatibleWithNativeTypeRector on a type alias nested in a union A @phpstan-type alias name is not resolved to the type it stands for, it becomes a NonExistingObjectType. So "@return ConfigArray|CustomConfig" over a native "array" looked like a contradiction and the tag was removed. The alias guard only matched when the whole @return type was a single IdentifierTypeNode. Look the name up in every identifier of the type node instead, which covers unions, nullables and intersections as well. Co-Authored-By: Claude Opus 5 (1M context) --- ...e_object_return_next_to_type_alias.php.inc | 36 ++++++++++++++++++ ...skip_union_of_phpstan_type_aliases.php.inc | 13 +++++++ ...urnTagIncompatibleWithNativeTypeRector.php | 37 ++++++++++++++++++- 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/remove_object_return_next_to_type_alias.php.inc create mode 100644 rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_union_of_phpstan_type_aliases.php.inc diff --git a/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/remove_object_return_next_to_type_alias.php.inc b/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/remove_object_return_next_to_type_alias.php.inc new file mode 100644 index 00000000000..0648711a0bb --- /dev/null +++ b/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/remove_object_return_next_to_type_alias.php.inc @@ -0,0 +1,36 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_union_of_phpstan_type_aliases.php.inc b/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_union_of_phpstan_type_aliases.php.inc new file mode 100644 index 00000000000..34e8a924967 --- /dev/null +++ b/rules-tests/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector/Fixture/skip_union_of_phpstan_type_aliases.php.inc @@ -0,0 +1,13 @@ +type instanceof IdentifierTypeNode - && isset($typeAliases[$returnTagValueNode->type->name]); + return $this->containsTypeAliasName($returnTagValueNode->type, $typeAliases); + } + + /** + * The alias can be nested in a composed type as well, e.g. "ConfigArray|CustomConfig" or "?ConfigArray" + * + * @param array $typeAliases + */ + private function containsTypeAliasName(TypeNode $typeNode, array $typeAliases): bool + { + if ($typeNode instanceof IdentifierTypeNode) { + return isset($typeAliases[$typeNode->name]); + } + + $hasTypeAliasName = false; + + // the traverser visits sub-nodes only, that is why the type node itself is checked above + $phpDocNodeTraverser = new PhpDocNodeTraverser(); + $phpDocNodeTraverser->traverseWithCallable($typeNode, '', static function (AstNode $astNode) use ( + $typeAliases, + &$hasTypeAliasName + ): ?int { + if ($astNode instanceof IdentifierTypeNode && isset($typeAliases[$astNode->name])) { + $hasTypeAliasName = true; + } + + return null; + }); + + return $hasTypeAliasName; } private function isReturnTemplate(PhpDocInfo $phpDocInfo, ReturnTagValueNode $returnTagValueNode): bool From a16c2d1f15cc870460533ae529fb163339556f2f Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 18 Aug 2026 15:39:49 +0200 Subject: [PATCH 2/3] stop traversal early once type alias name found --- .../RemoveReturnTagIncompatibleWithNativeTypeRector.php | 1 + 1 file changed, 1 insertion(+) diff --git a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php index 9fa7f4b1964..d5dc9306791 100644 --- a/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php +++ b/rules/DeadCode/Rector/ClassMethod/RemoveReturnTagIncompatibleWithNativeTypeRector.php @@ -192,6 +192,7 @@ private function containsTypeAliasName(TypeNode $typeNode, array $typeAliases): ): ?int { if ($astNode instanceof IdentifierTypeNode && isset($typeAliases[$astNode->name])) { $hasTypeAliasName = true; + return PhpDocNodeTraverser::STOP_TRAVERSAL; } return null; From e6e08bc36cf3e94d81b86e1d2e609e8c8529bb98 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 18 Aug 2026 15:44:56 +0200 Subject: [PATCH 3/3] fix deprecated RobotLoader::setTempDirectory(), use setCacheDirectory() --- scripts/src/Finder/RectorClassFinder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/src/Finder/RectorClassFinder.php b/scripts/src/Finder/RectorClassFinder.php index 3e5740cfe35..ae7a1d7163f 100644 --- a/scripts/src/Finder/RectorClassFinder.php +++ b/scripts/src/Finder/RectorClassFinder.php @@ -21,7 +21,7 @@ public function find(array $dirs): array $robotLoader->acceptFiles = ['*Rector.php']; $robotLoader->addDirectory(...$dirs); - $robotLoader->setTempDirectory(sys_get_temp_dir() . '/rector-rules'); + $robotLoader->setCacheDirectory(sys_get_temp_dir() . '/rector-rules'); $robotLoader->refresh(); /** @var array $rectorClasses */