From 1e186ad00e58592c21da91d42c2a49b1c4446b32 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 2 Sep 2026 11:14:10 +0200 Subject: [PATCH] [TypeDeclarationDocblocks] Fix invalid array-in-key docblock when narrowing long array unions sharedArrayStructure() returns a full array structure, but narrowToAlwaysKnownArrayType() placed it in the key slot of a new ArrayType, producing invalid types like array. Return the shared structure directly instead. --- ...kip_heterogeneous_nested_array_key.php.inc | 21 +++++++++++++++++++ .../TypeManipulator/TypeNormalizer.php | 8 +++++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/skip_heterogeneous_nested_array_key.php.inc diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/skip_heterogeneous_nested_array_key.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/skip_heterogeneous_nested_array_key.php.inc new file mode 100644 index 00000000000..fa57efe6e77 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/Class_/ClassMethodArrayDocblockParamFromLocalCallsRector/Fixture/skip_heterogeneous_nested_array_key.php.inc @@ -0,0 +1,21 @@ +sink([["x" => 1], "s"]); + } + + public function two() + { + return $this->sink([[["d" => 1]]]); + } + + protected function sink(array $data) + { + return $data; + } +} diff --git a/rules/Privatization/TypeManipulator/TypeNormalizer.php b/rules/Privatization/TypeManipulator/TypeNormalizer.php index 11ce83a5cc5..8594031162a 100644 --- a/rules/Privatization/TypeManipulator/TypeNormalizer.php +++ b/rules/Privatization/TypeManipulator/TypeNormalizer.php @@ -196,10 +196,14 @@ private function narrowToAlwaysKnownArrayType(UnionType $unionType): ?ArrayType return null; } - $arrayUniqueKeyType = $this->arrayTypeLeastCommonDenominatorResolver->sharedArrayStructure( + $sharedArrayStructure = $this->arrayTypeLeastCommonDenominatorResolver->sharedArrayStructure( ...$unionType->getTypes() ); - return new ArrayType($arrayUniqueKeyType, new MixedType()); + if (! $sharedArrayStructure instanceof ArrayType) { + return null; + } + + return $sharedArrayStructure; } /**