diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 44bc014119..5c9dad5762 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -210,7 +210,9 @@ public function specifyTypesInCondition( } $argType = $scope->getType($exprNode->getArgs()[0]->value); if ($argType->isArray()->yes()) { - return $this->create($exprNode->getArgs()[0]->value, new NonEmptyArrayType(), $newContext, false, $scope); + $funcTypes = $this->create($exprNode, $constantType, $context, false, $scope); + $valueTypes = $this->create($exprNode->getArgs()[0]->value, new NonEmptyArrayType(), $newContext, false, $scope); + return $funcTypes->unionWith($valueTypes); } } } @@ -230,7 +232,9 @@ public function specifyTypesInCondition( } $argType = $scope->getType($exprNode->getArgs()[0]->value); if ($argType instanceof StringType) { - return $this->create($exprNode->getArgs()[0]->value, new AccessoryNonEmptyStringType(), $newContext, false, $scope); + $funcTypes = $this->create($exprNode, $constantType, $context, false, $scope); + $valueTypes = $this->create($exprNode->getArgs()[0]->value, new AccessoryNonEmptyStringType(), $newContext, false, $scope); + return $funcTypes->unionWith($valueTypes); } } } diff --git a/tests/PHPStan/Analyser/TypeSpecifierTest.php b/tests/PHPStan/Analyser/TypeSpecifierTest.php index d86f095c54..e0240946e5 100644 --- a/tests/PHPStan/Analyser/TypeSpecifierTest.php +++ b/tests/PHPStan/Analyser/TypeSpecifierTest.php @@ -1022,6 +1022,59 @@ public function dataCondition(): array ], [], ], + [ + new Expr\BinaryOp\BooleanAnd( + $this->createFunctionCall('is_array', 'foo'), + new Expr\BinaryOp\GreaterOrEqual( + new FuncCall( + new Name('count'), + [new Arg(new Variable('foo'))], + ), + new LNumber(2), + ), + ), + [ + '$foo' => 'non-empty-array', + 'count($foo)' => 'mixed~int|false|null', + ], + [], + ], + [ + new Expr\BinaryOp\BooleanAnd( + $this->createFunctionCall('is_array', 'foo'), + new Identical( + new FuncCall( + new Name('count'), + [new Arg(new Variable('foo'))], + ), + new LNumber(2), + ), + ), + [ + '$foo' => 'non-empty-array', + 'count($foo)' => '2', + ], + [], + ], + [ + new Expr\BinaryOp\BooleanAnd( + $this->createFunctionCall('is_string', 'foo'), + new NotIdentical( + new FuncCall( + new Name('strlen'), + [new Arg(new Variable('foo'))], + ), + new LNumber(0), + ), + ), + [ + '$foo' => 'non-empty-string', + 'strlen($foo)' => '~0', + ], + [ + '$foo' => '~non-empty-string', + ], + ], ]; } diff --git a/tests/PHPStan/Analyser/data/bug-2648.php b/tests/PHPStan/Analyser/data/bug-2648.php index 23797170a1..11087dfbaa 100644 --- a/tests/PHPStan/Analyser/data/bug-2648.php +++ b/tests/PHPStan/Analyser/data/bug-2648.php @@ -37,6 +37,8 @@ public function doBar(array $list): void assertType('int<0, max>', count($list)); if (count($list) === 1) { + assertType('1', count($list)); + $list[] = false; assertType('int<1, max>', count($list)); break; }