Skip to content

Commit f08de42

Browse files
authored
Fix phpstan/phpstan#14223: Variable $ in empty() always exists and is not falsy. (#5124)
1 parent d6b6f77 commit f08de42

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

src/Type/Php/ArrayCountValuesDynamicReturnTypeExtension.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function getTypeFromFunctionCall(
4444
$inputType = $scope->getType($args[0]->value);
4545

4646
$arrayTypes = $inputType->getArrays();
47+
$isInputNonEmpty = $inputType->isIterableAtLeastOnce()->yes();
4748

4849
$outputTypes = [];
4950
$allowedValues = new UnionType([new IntegerType(), new StringType()]);
@@ -54,10 +55,16 @@ public function getTypeFromFunctionCall(
5455
continue;
5556
}
5657

57-
$outputTypes[] = new IntersectionType([
58-
new ArrayType($itemType->toArrayKey(), IntegerRangeType::fromInterval(1, null)),
59-
new NonEmptyArrayType(),
60-
]);
58+
$resultArrayType = new ArrayType($itemType->toArrayKey(), IntegerRangeType::fromInterval(1, null));
59+
60+
if ($isInputNonEmpty) {
61+
$outputTypes[] = new IntersectionType([
62+
$resultArrayType,
63+
new NonEmptyArrayType(),
64+
]);
65+
} else {
66+
$outputTypes[] = $resultArrayType;
67+
}
6168
}
6269

6370
if (count($outputTypes) === 0) {

tests/PHPStan/Analyser/nsrt/array-count-values.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function returnsStringOrObjectArray(): array
2525
}
2626

2727
// Objects are ignored by array_count_values, with a warning emitted.
28-
assertType('non-empty-array<string, int<1, max>>', array_count_values(returnsStringOrObjectArray()));
28+
assertType('array<string, int<1, max>>', array_count_values(returnsStringOrObjectArray()));
2929

3030
class StringableObject
3131
{
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Bug14223;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @param list<string> $a1
9+
*/
10+
function doFoo(array $a1): void
11+
{
12+
$a2 = array_count_values($a1);
13+
assertType('array<string, int<1, max>>', $a2);
14+
}
15+
16+
/**
17+
* @param non-empty-list<string> $a1
18+
*/
19+
function doBar(array $a1): void
20+
{
21+
$a2 = array_count_values($a1);
22+
assertType('non-empty-array<string, int<1, max>>', $a2);
23+
}

0 commit comments

Comments
 (0)