Skip to content

Commit b1fd47b

Browse files
cs278ondrejmirtes
authored andcommitted
Invalidate array type info when using array_{push,pop,shift,unshift}
1 parent 8376548 commit b1fd47b

3 files changed

Lines changed: 37 additions & 4 deletions

File tree

src/Analyser/NodeScopeResolver.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,14 +1374,14 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
13741374
}
13751375
}
13761376

1377-
$scope = $scope->specifyExpressionType(
1377+
$scope = $scope->invalidateExpression($arrayArg)->specifyExpressionType(
13781378
$arrayArg,
13791379
TypeCombinator::union(...$resultArrayTypes)
13801380
);
13811381
} else {
13821382
$arrays = TypeUtils::getAnyArrays($scope->getType($arrayArg));
13831383
if (count($arrays) > 0) {
1384-
$scope = $scope->specifyExpressionType($arrayArg, TypeCombinator::union(...$arrays));
1384+
$scope = $scope->invalidateExpression($arrayArg)->specifyExpressionType($arrayArg, TypeCombinator::union(...$arrays));
13851385
}
13861386
}
13871387
}
@@ -1421,7 +1421,7 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
14211421
$arrayType = $arrayType->setOffsetValueType(null, $argType);
14221422
}
14231423

1424-
$scope = $scope->specifyExpressionType($arrayArg, TypeCombinator::intersect($arrayType, new NonEmptyArrayType()));
1424+
$scope = $scope->invalidateExpression($arrayArg)->specifyExpressionType($arrayArg, TypeCombinator::intersect($arrayType, new NonEmptyArrayType()));
14251425
} elseif (count($constantArrays) > 0) {
14261426
$defaultArrayBuilder = ConstantArrayTypeBuilder::createEmpty();
14271427
foreach ($argumentTypes as $argType) {
@@ -1443,7 +1443,7 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
14431443
$arrayTypes[] = $arrayType;
14441444
}
14451445

1446-
$scope = $scope->specifyExpressionType(
1446+
$scope = $scope->invalidateExpression($arrayArg)->specifyExpressionType(
14471447
$arrayArg,
14481448
TypeCombinator::union(...$arrayTypes)
14491449
);

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9762,6 +9762,11 @@ public function dataBug2443(): array
97629762
return $this->gatherAssertTypes(__DIR__ . '/data/bug-2443.php');
97639763
}
97649764

9765+
public function dataBug2750(): array
9766+
{
9767+
return $this->gatherAssertTypes(__DIR__ . '/data/bug-2750.php');
9768+
}
9769+
97659770
/**
97669771
* @dataProvider dataBug2574
97679772
* @dataProvider dataBug2577
@@ -9787,6 +9792,7 @@ public function dataBug2443(): array
97879792
* @dataProvider dataBug2822
97889793
* @dataProvider dataBug2835
97899794
* @dataProvider dataBug2443
9795+
* @dataProvider dataBug2750
97909796
* @param ConstantStringType $expectedType
97919797
* @param Type $actualType
97929798
*/
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Analyser\Bug2750;
4+
5+
use function PHPStan\Analyser\assertType;
6+
7+
function (array $input) {
8+
\assert(count($input) > 0);
9+
assertType('int<1, max>', count($input));
10+
array_shift($input);
11+
assertType('int', count($input));
12+
13+
\assert(count($input) > 0);
14+
assertType('int<1, max>', count($input));
15+
array_pop($input);
16+
assertType('int', count($input));
17+
18+
\assert(count($input) > 0);
19+
assertType('int<1, max>', count($input));
20+
array_unshift($input, 'test');
21+
assertType('int', count($input));
22+
23+
\assert(count($input) > 0);
24+
assertType('int<1, max>', count($input));
25+
array_push($input, 'nope');
26+
assertType('int', count($input));
27+
};

0 commit comments

Comments
 (0)