Skip to content

Commit eefb449

Browse files
phpstan-botclaude
andcommitted
Move initializedEmpty into ConstantArrayType to avoid heuristic reconstruction
Instead of scanning keys and nextAutoIndexes in createFromConstantArray to reconstruct whether an array was empty-initialized, store the initializedEmpty flag directly in ConstantArrayType. This eliminates the elseif heuristic and ensures the flag persists naturally through setOffsetValueType round-trips via recreate(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ee2c7a3 commit eefb449

File tree

2 files changed

+10
-18
lines changed

2 files changed

+10
-18
lines changed

src/Type/Constant/ConstantArrayType.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ public function __construct(
107107
private array $nextAutoIndexes = [0],
108108
private array $optionalKeys = [],
109109
?TrinaryLogic $isList = null,
110+
private bool $initializedEmpty = false,
110111
)
111112
{
112113
assert(count($keyTypes) === count($valueTypes));
@@ -136,7 +137,7 @@ protected function recreate(
136137
?TrinaryLogic $isList = null,
137138
): self
138139
{
139-
return new self($keyTypes, $valueTypes, $nextAutoIndexes, $optionalKeys, $isList);
140+
return new self($keyTypes, $valueTypes, $nextAutoIndexes, $optionalKeys, $isList, $this->initializedEmpty);
140141
}
141142

142143
public function getConstantArrays(): array
@@ -212,6 +213,11 @@ public function getNextAutoIndexes(): array
212213
return $this->nextAutoIndexes;
213214
}
214215

216+
public function isInitializedEmpty(): bool
217+
{
218+
return $this->initializedEmpty;
219+
}
220+
215221
/**
216222
* @return int[]
217223
*/

src/Type/Constant/ConstantArrayTypeBuilder.php

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,8 @@ public static function createFromConstantArray(ConstantArrayType $startArrayType
7575
$startArrayType->isList(),
7676
);
7777

78-
$phpVersion = PhpVersionStaticAccessor::getInstance();
79-
if (
80-
!$phpVersion->updatesAutoIncrementKeyForNegativeValues()
81-
&& $phpVersion->updatesAutoIncrementKeyForNegativeValuesInNonEmptyInitializer()
82-
) {
83-
if (count($startArrayType->getKeyTypes()) === 0) {
84-
$builder->initializedEmpty = true;
85-
} elseif (max($startArrayType->getNextAutoIndexes()) === 0) {
86-
foreach ($startArrayType->getKeyTypes() as $keyType) {
87-
if ($keyType instanceof ConstantIntegerType && $keyType->getValue() < 0) {
88-
$builder->initializedEmpty = true;
89-
break;
90-
}
91-
}
92-
}
93-
}
78+
$builder->initializedEmpty = $startArrayType->isInitializedEmpty()
79+
|| count($startArrayType->getKeyTypes()) === 0;
9480

9581
if (count($startArrayType->getKeyTypes()) > self::ARRAY_COUNT_LIMIT) {
9682
$builder->degradeToGeneralArray(true);
@@ -393,7 +379,7 @@ public function getArray(): Type
393379
if (!$this->degradeToGeneralArray) {
394380
/** @var list<ConstantIntegerType|ConstantStringType> $keyTypes */
395381
$keyTypes = $this->keyTypes;
396-
return new ConstantArrayType($keyTypes, $this->valueTypes, $this->nextAutoIndexes, $this->optionalKeys, $this->isList);
382+
return new ConstantArrayType($keyTypes, $this->valueTypes, $this->nextAutoIndexes, $this->optionalKeys, $this->isList, $this->initializedEmpty);
397383
}
398384

399385
if ($this->degradeClosures === true) {

0 commit comments

Comments
 (0)