Skip to content

Commit

Permalink
fix array_splice with non-array replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
schlndh authored and ondrejmirtes committed Jun 28, 2023
1 parent 828b269 commit 9a0bc5e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,8 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
$arrayArgType = $scope->getType($arrayArg);
$valueType = $arrayArgType->getIterableValueType();
if (count($expr->getArgs()) >= 4) {
$valueType = TypeCombinator::union($valueType, $scope->getType($expr->getArgs()[3]->value)->getIterableValueType());
$replacementType = $scope->getType($expr->getArgs()[3]->value)->toArray();
$valueType = TypeCombinator::union($valueType, $replacementType->getIterableValueType());
}
$scope = $scope->invalidateExpression($arrayArg)->assignExpression(
$arrayArg,
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,7 @@ public function dataFileAsserts(): iterable
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/gettype.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/array_splice.php');
}

/**
Expand Down
61 changes: 61 additions & 0 deletions tests/PHPStan/Analyser/data/array_splice.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace ArraySplice;

use function PHPStan\Testing\assertType;

final class Foo
{
/** @var bool */
public $abc = false;

/** @var string */
public $def = 'def';
}

/**
* @param array<int, int> $arr
* @return void
*/
function insertViaArraySplice(array $arr): void
{
$brr = $arr;
array_splice($brr, 0, 0, 1);
assertType('array<int, int>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, [1]);
assertType('array<int, int>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, '');
assertType('array<int, \'\'|int>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, ['']);
assertType('array<int, \'\'|int>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, null);
assertType('array<int, int>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, [null]);
assertType('array<int, int|null>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, new Foo());
assertType('array<int, bool|int|string>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, [new \stdClass()]);
assertType('array<int, int|stdClass>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, false);
assertType('array<int, int|false>', $brr);

$brr = $arr;
array_splice($brr, 0, 0, [false]);
assertType('array<int, int|false>', $brr);
}

0 comments on commit 9a0bc5e

Please sign in to comment.