Skip to content

Commit 9a0bc5e

Browse files
schlndhondrejmirtes
authored andcommitted
fix array_splice with non-array replacement
1 parent 828b269 commit 9a0bc5e

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

src/Analyser/NodeScopeResolver.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -2010,7 +2010,8 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
20102010
$arrayArgType = $scope->getType($arrayArg);
20112011
$valueType = $arrayArgType->getIterableValueType();
20122012
if (count($expr->getArgs()) >= 4) {
2013-
$valueType = TypeCombinator::union($valueType, $scope->getType($expr->getArgs()[3]->value)->getIterableValueType());
2013+
$replacementType = $scope->getType($expr->getArgs()[3]->value)->toArray();
2014+
$valueType = TypeCombinator::union($valueType, $replacementType->getIterableValueType());
20142015
}
20152016
$scope = $scope->invalidateExpression($arrayArg)->assignExpression(
20162017
$arrayArg,

tests/PHPStan/Analyser/NodeScopeResolverTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,7 @@ public function dataFileAsserts(): iterable
12881288
}
12891289

12901290
yield from $this->gatherAssertTypes(__DIR__ . '/data/gettype.php');
1291+
yield from $this->gatherAssertTypes(__DIR__ . '/data/array_splice.php');
12911292
}
12921293

12931294
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace ArraySplice;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
final class Foo
8+
{
9+
/** @var bool */
10+
public $abc = false;
11+
12+
/** @var string */
13+
public $def = 'def';
14+
}
15+
16+
/**
17+
* @param array<int, int> $arr
18+
* @return void
19+
*/
20+
function insertViaArraySplice(array $arr): void
21+
{
22+
$brr = $arr;
23+
array_splice($brr, 0, 0, 1);
24+
assertType('array<int, int>', $brr);
25+
26+
$brr = $arr;
27+
array_splice($brr, 0, 0, [1]);
28+
assertType('array<int, int>', $brr);
29+
30+
$brr = $arr;
31+
array_splice($brr, 0, 0, '');
32+
assertType('array<int, \'\'|int>', $brr);
33+
34+
$brr = $arr;
35+
array_splice($brr, 0, 0, ['']);
36+
assertType('array<int, \'\'|int>', $brr);
37+
38+
$brr = $arr;
39+
array_splice($brr, 0, 0, null);
40+
assertType('array<int, int>', $brr);
41+
42+
$brr = $arr;
43+
array_splice($brr, 0, 0, [null]);
44+
assertType('array<int, int|null>', $brr);
45+
46+
$brr = $arr;
47+
array_splice($brr, 0, 0, new Foo());
48+
assertType('array<int, bool|int|string>', $brr);
49+
50+
$brr = $arr;
51+
array_splice($brr, 0, 0, [new \stdClass()]);
52+
assertType('array<int, int|stdClass>', $brr);
53+
54+
$brr = $arr;
55+
array_splice($brr, 0, 0, false);
56+
assertType('array<int, int|false>', $brr);
57+
58+
$brr = $arr;
59+
array_splice($brr, 0, 0, [false]);
60+
assertType('array<int, int|false>', $brr);
61+
}

0 commit comments

Comments
 (0)