Skip to content

Commit f78547c

Browse files
herndlmondrejmirtes
authored andcommitted
Improve ConstantArrayType::sliceArray() with non constant integer args
1 parent 9015e3b commit f78547c

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

Diff for: src/Type/Constant/ConstantArrayType.php

+17-2
Original file line numberDiff line numberDiff line change
@@ -926,8 +926,23 @@ public function sliceArray(Type $offsetType, Type $lengthType, TrinaryLogic $pre
926926
return $this;
927927
}
928928

929-
$offset = $offsetType instanceof ConstantIntegerType ? $offsetType->getValue() : 0;
930-
$length = $lengthType instanceof ConstantIntegerType ? $lengthType->getValue() : $keyTypesCount;
929+
$offset = $offsetType instanceof ConstantIntegerType ? $offsetType->getValue() : null;
930+
931+
if ($lengthType instanceof ConstantIntegerType) {
932+
$length = $lengthType->getValue();
933+
} elseif ($lengthType->isNull()->yes()) {
934+
$length = $keyTypesCount;
935+
} else {
936+
$length = null;
937+
}
938+
939+
if ($offset === null || $length === null) {
940+
$builder = ConstantArrayTypeBuilder::createFromConstantArray($this);
941+
$builder->degradeToGeneralArray();
942+
943+
return $builder->getArray()
944+
->sliceArray($offsetType, $lengthType, $preserveKeys);
945+
}
931946

932947
if ($length < 0) {
933948
// Negative lengths prevent access to the most right n elements

Diff for: tests/PHPStan/Analyser/nsrt/array-slice.php

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public function constantArrays(array $arr): void
4343
/** @var array{17: 'foo', b: 'bar', 19: 'baz'} $arr */
4444
assertType('array{b: \'bar\', 0: \'baz\'}', array_slice($arr, 1, 2));
4545
assertType('array{b: \'bar\', 19: \'baz\'}', array_slice($arr, 1, 2, true));
46+
assertType('array<17|19|\'b\', \'bar\'|\'baz\'|\'foo\'>', array_slice($arr, rand(0, 1) ? 0 : 1, rand(0, 1) ? 0 : 1));
4647

4748
/** @var array{17: 'foo', 19: 'bar', 21: 'baz'}|array{foo: 17, bar: 19, baz: 21} $arr */
4849
assertType('array{\'bar\', \'baz\'}|array{bar: 19, baz: 21}', array_slice($arr, 1, 2));

0 commit comments

Comments
 (0)