Skip to content

Commit

Permalink
Invalidate array type info when using array_{push,pop,shift,unshift}
Browse files Browse the repository at this point in the history
  • Loading branch information
cs278 authored and ondrejmirtes committed Jan 14, 2020
1 parent 8376548 commit b1fd47b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1374,14 +1374,14 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
}
}

$scope = $scope->specifyExpressionType(
$scope = $scope->invalidateExpression($arrayArg)->specifyExpressionType(
$arrayArg,
TypeCombinator::union(...$resultArrayTypes)
);
} else {
$arrays = TypeUtils::getAnyArrays($scope->getType($arrayArg));
if (count($arrays) > 0) {
$scope = $scope->specifyExpressionType($arrayArg, TypeCombinator::union(...$arrays));
$scope = $scope->invalidateExpression($arrayArg)->specifyExpressionType($arrayArg, TypeCombinator::union(...$arrays));
}
}
}
Expand Down Expand Up @@ -1421,7 +1421,7 @@ function (MutatingScope $scope) use ($expr, $nodeCallback, $context): Expression
$arrayType = $arrayType->setOffsetValueType(null, $argType);
}

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

$scope = $scope->specifyExpressionType(
$scope = $scope->invalidateExpression($arrayArg)->specifyExpressionType(
$arrayArg,
TypeCombinator::union(...$arrayTypes)
);
Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9762,6 +9762,11 @@ public function dataBug2443(): array
return $this->gatherAssertTypes(__DIR__ . '/data/bug-2443.php');
}

public function dataBug2750(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/bug-2750.php');
}

/**
* @dataProvider dataBug2574
* @dataProvider dataBug2577
Expand All @@ -9787,6 +9792,7 @@ public function dataBug2443(): array
* @dataProvider dataBug2822
* @dataProvider dataBug2835
* @dataProvider dataBug2443
* @dataProvider dataBug2750
* @param ConstantStringType $expectedType
* @param Type $actualType
*/
Expand Down
27 changes: 27 additions & 0 deletions tests/PHPStan/Analyser/data/bug-2750.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Analyser\Bug2750;

use function PHPStan\Analyser\assertType;

function (array $input) {
\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_shift($input);
assertType('int', count($input));

\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_pop($input);
assertType('int', count($input));

\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_unshift($input, 'test');
assertType('int', count($input));

\assert(count($input) > 0);
assertType('int<1, max>', count($input));
array_push($input, 'nope');
assertType('int', count($input));
};

0 comments on commit b1fd47b

Please sign in to comment.