Skip to content

Commit 5901a55

Browse files
VincentLangletphpstan-bot
authored andcommitted
Fix array_splice not resetting integer keys of the input array
- Generalize specific integer key types (e.g. 10|20|30) to int in ArrayType::spliceArray() - Uses TypeTraverser to only affect integer parts of union key types, preserving string keys - New regression test in tests/PHPStan/Analyser/nsrt/bug-14037.php - The root cause was that ArrayType::spliceArray() preserved the original key type verbatim, but PHP's array_splice re-indexes integer keys to 0, 1, 2, ...
1 parent 1b1f48c commit 5901a55

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/Type/ArrayType.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,8 +521,20 @@ public function spliceArray(Type $offsetType, Type $lengthType, Type $replacemen
521521
return new ConstantArrayType([], []);
522522
}
523523

524+
$keyType = TypeTraverser::map($this->getIterableKeyType(), static function (Type $type, callable $traverse): Type {
525+
if ($type instanceof UnionType) {
526+
return $traverse($type);
527+
}
528+
529+
if ($type->isInteger()->yes()) {
530+
return new IntegerType();
531+
}
532+
533+
return $type;
534+
});
535+
524536
$arrayType = new self(
525-
TypeCombinator::union($this->getIterableKeyType(), $replacementArrayType->getKeysArray()->getIterableKeyType()),
537+
TypeCombinator::union($keyType, $replacementArrayType->getKeysArray()->getIterableKeyType()),
526538
TypeCombinator::union($this->getIterableValueType(), $replacementArrayType->getIterableValueType()),
527539
);
528540

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Bug14037;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @param array<10|20|30|'a', mixed> $a
9+
*/
10+
function splice(array $a): void {
11+
array_splice($a, 0, 0);
12+
assertType("array<'a'|int, mixed>", $a);
13+
}

0 commit comments

Comments
 (0)