Skip to content

Commit 3a9225d

Browse files
committed
Preserve constant array when setting a integer-range key
1 parent 5c8ae3e commit 3a9225d

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

src/Type/Constant/ConstantArrayType.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,12 @@ public function getOffsetValueType(Type $offsetType): Type
694694
public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type
695695
{
696696
if ($offsetType !== null && $valueType->isConstantScalarValue()->yes()) {
697-
$constantScalars = $offsetType->getConstantScalarTypes();
697+
if ($offsetType instanceof IntegerRangeType) {
698+
$constantScalars = $offsetType->getFiniteTypes();
699+
} else {
700+
$constantScalars = $offsetType->getConstantScalarTypes();
701+
}
702+
698703
$constantScalarsCount = count($constantScalars);
699704
if ($constantScalarsCount > 1 && $constantScalarsCount < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) {
700705
$arrays = [];
@@ -716,7 +721,12 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $uni
716721
public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type
717722
{
718723
if ($valueType->isConstantScalarValue()->yes()) {
719-
$constantScalars = $offsetType->getConstantScalarTypes();
724+
if ($offsetType instanceof IntegerRangeType) {
725+
$constantScalars = $offsetType->getFiniteTypes();
726+
} else {
727+
$constantScalars = $offsetType->getConstantScalarTypes();
728+
}
729+
720730
$constantScalarsCount = count($constantScalars);
721731
if ($constantScalarsCount > 1 && $constantScalarsCount < ConstantArrayTypeBuilder::ARRAY_COUNT_LIMIT) {
722732
$arrays = [];

tests/PHPStan/Analyser/nsrt/constant-array-type-set.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function doFoo(int $i)
2727
/** @var int<0, 2> $offset2 */
2828
$offset2 = doFoo();
2929
$d[$offset2] = true;
30-
assertType('array{bool, bool, bool}', $d);
30+
assertType('array{false, false, true}|array{false, true, false}|array{true, false, false}', $d);
3131

3232
$e = [false, false, false];
3333
/** @var 0|1|2|3 $offset3 */
@@ -50,7 +50,7 @@ public function doBar(int $offset): void
5050
{
5151
$a = [false, false, false];
5252
$a[$offset] = true;
53-
assertType('array{bool, bool, false}', $a);
53+
assertType('array{false, true, false}|array{true, false, false}', $a);
5454
}
5555

5656
/**
@@ -94,7 +94,7 @@ public function doBar5(int $offset): void
9494
{
9595
$a = [false, false, false];
9696
$a[$offset] = true;
97-
assertType('non-empty-array<int<0, 4>, bool>', $a);
97+
assertType('array{0: false, 1: false, 2: false, 4: true}|array{false, false, false, true}|array{false, false, true}|array{false, true, false}|array{true, false, false}', $a);
9898
}
9999

100100
public function doBar6(bool $offset): void

tests/PHPStan/Analyser/nsrt/set-constant-union-offset-on-constant-array.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,14 @@ public function doFoo(array $a): void
1717
assertType('array{foo: int, a: 256}|array{foo: int, b: 256}', $a);
1818
}
1919

20+
/**
21+
* @param array{foo: int} $a
22+
* @param int<1,5> $intRange
23+
*/
24+
public function doBar(array $a, $intRange): void
25+
{
26+
$a[$intRange] = 256;
27+
assertType('array{foo: int, 1: 256}|array{foo: int, 2: 256}|array{foo: int, 3: 256}|array{foo: int, 4: 256}|array{foo: int, 5: 256}', $a);
28+
}
29+
2030
}

0 commit comments

Comments
 (0)