Skip to content

Commit a906bdb

Browse files
phpstan-botclaude
andcommitted
Revert ConstantArrayTypeBuilder changes, decompose union offsets in callers instead
Move the union offset decomposition entirely into flipArray() and fillKeysArray() — each individual scalar type is passed to the builder separately with optional=true, avoiding both the value-replacement and partial-match degradation issues without modifying the builder. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 889ac99 commit a906bdb

2 files changed

Lines changed: 33 additions & 14 deletions

File tree

src/Type/Constant/ConstantArrayType.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -969,9 +969,19 @@ public function fillKeysArray(Type $valueType): Type
969969
return $stringKeyType;
970970
}
971971

972-
$builder->setOffsetValueType($stringKeyType, $valueType, $this->isOptionalKey($i) || count($stringKeyType->getConstantScalarTypes()) > 1);
972+
$offsetType = $stringKeyType;
973973
} else {
974-
$builder->setOffsetValueType($keyType, $valueType, $this->isOptionalKey($i) || count($keyType->getConstantScalarTypes()) > 1);
974+
$offsetType = $keyType;
975+
}
976+
977+
$isOptional = $this->isOptionalKey($i);
978+
$scalarTypes = $offsetType->getConstantScalarTypes();
979+
if (count($scalarTypes) > 1) {
980+
foreach ($scalarTypes as $scalarType) {
981+
$builder->setOffsetValueType($scalarType, $valueType, true);
982+
}
983+
} else {
984+
$builder->setOffsetValueType($offsetType, $valueType, $isOptional);
975985
}
976986
}
977987

@@ -984,12 +994,25 @@ public function flipArray(): Type
984994

985995
foreach ($this->keyTypes as $i => $keyType) {
986996
$valueType = $this->valueTypes[$i];
987-
$offsetType = $valueType->toArrayKey();
988-
$builder->setOffsetValueType(
989-
$offsetType,
990-
$keyType,
991-
$this->isOptionalKey($i) || count($offsetType->getConstantScalarTypes()) > 1,
992-
);
997+
$isOptional = $this->isOptionalKey($i);
998+
$arrayKeyType = $valueType->toArrayKey();
999+
1000+
$scalarTypes = $arrayKeyType->getConstantScalarTypes();
1001+
if (count($scalarTypes) > 1) {
1002+
foreach ($scalarTypes as $scalarType) {
1003+
$builder->setOffsetValueType(
1004+
$scalarType,
1005+
$keyType,
1006+
true,
1007+
);
1008+
}
1009+
} else {
1010+
$builder->setOffsetValueType(
1011+
$arrayKeyType,
1012+
$keyType,
1013+
$isOptional,
1014+
);
1015+
}
9931016
}
9941017

9951018
return $builder->getArray();

src/Type/Constant/ConstantArrayTypeBuilder.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
270270
if (count($scalarTypes) > 0 && count($scalarTypes) < self::ARRAY_COUNT_LIMIT) {
271271
$match = true;
272272
$hasMatch = false;
273-
$unmatchedScalarTypes = [];
274273
$valueTypes = $this->valueTypes;
275274
foreach ($scalarTypes as $scalarType) {
276275
$offsetMatch = false;
@@ -294,7 +293,6 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
294293
continue;
295294
}
296295

297-
$unmatchedScalarTypes[] = $scalarType;
298296
$match = false;
299297
}
300298

@@ -303,10 +301,8 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
303301
return;
304302
}
305303

306-
if (!$hasMatch || $optional) {
307-
$this->valueTypes = $valueTypes;
308-
309-
foreach ($unmatchedScalarTypes as $scalarType) {
304+
if (!$hasMatch) {
305+
foreach ($scalarTypes as $scalarType) {
310306
$this->keyTypes[] = $scalarType;
311307
$this->valueTypes[] = $valueType;
312308
$this->optionalKeys[] = count($this->keyTypes) - 1;

0 commit comments

Comments
 (0)