diff --git a/src/Type/ArrayType.php b/src/Type/ArrayType.php index 88a7617901..9f87759790 100644 --- a/src/Type/ArrayType.php +++ b/src/Type/ArrayType.php @@ -371,6 +371,22 @@ 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()) { + $newItemType = $this->itemType; + foreach ($valueType->getConstantArrays() 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); } }