From 457b1958e89bae5c7f4cebea26ee7a47ab77e627 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 27 Sep 2025 13:49:25 +0200 Subject: [PATCH 1/2] Improve ConstantArrayType inference --- src/Type/ArrayType.php | 17 +++++++++++++++++ tests/PHPStan/Analyser/nsrt/bug-11846.php | 6 +++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Type/ArrayType.php b/src/Type/ArrayType.php index 88a7617901..35362de99f 100644 --- a/src/Type/ArrayType.php +++ b/src/Type/ArrayType.php @@ -371,6 +371,23 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type { + if ($this->itemType->isConstantArray()->yes() && $valueType->isConstantArray()->yes()) { + $constArrays = $valueType->getConstantArrays(); + $newItemType = $this->itemType; + foreach ($constArrays as $constArray) { + foreach ($constArray->getKeyTypes() as $keyType) { + $newItemType = $newItemType->setExistingOffsetValueType($keyType, $constArray->getOffsetValueType($keyType)); + } + } + + if ($newItemType !== $this->itemType) { + return new self( + $this->keyType, + $newItemType, + ); + } + } + return new self( $this->keyType, TypeCombinator::union($this->itemType, $valueType), diff --git a/tests/PHPStan/Analyser/nsrt/bug-11846.php b/tests/PHPStan/Analyser/nsrt/bug-11846.php index 06fbcd8313..02ace75d07 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-11846.php +++ b/tests/PHPStan/Analyser/nsrt/bug-11846.php @@ -13,16 +13,16 @@ function demo(): void $outerList[$id] = []; array_push($outerList[$id], []); } - assertType('non-empty-array<1|2, array{}|array{array{}}>', $outerList); + assertType('non-empty-array<1|2, array{array{}}>', $outerList); foreach ($outerList as $key => $outerElement) { $result = false; - assertType('array{}|array{array{}}', $outerElement); + assertType('array{array{}}', $outerElement); foreach ($outerElement as $innerElement) { $result = true; } - assertType('bool', $result); // could be 'true' + assertType('true', $result); } } From 724286f27f7af263355c36690ed0e679c6185fdd Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 27 Sep 2025 13:51:27 +0200 Subject: [PATCH 2/2] Update ArrayType.php --- src/Type/ArrayType.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Type/ArrayType.php b/src/Type/ArrayType.php index 35362de99f..9f87759790 100644 --- a/src/Type/ArrayType.php +++ b/src/Type/ArrayType.php @@ -372,9 +372,8 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type { if ($this->itemType->isConstantArray()->yes() && $valueType->isConstantArray()->yes()) { - $constArrays = $valueType->getConstantArrays(); $newItemType = $this->itemType; - foreach ($constArrays as $constArray) { + foreach ($valueType->getConstantArrays() as $constArray) { foreach ($constArray->getKeyTypes() as $keyType) { $newItemType = $newItemType->setExistingOffsetValueType($keyType, $constArray->getOffsetValueType($keyType)); }