Skip to content

Commit c6e0450

Browse files
authored
Fix count() regression
1 parent 17d4a03 commit c6e0450

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

src/Analyser/TypeSpecifier.php

+2
Original file line numberDiff line numberDiff line change
@@ -1063,10 +1063,12 @@ private function specifyTypesForCountFuncCall(
10631063

10641064
$isConstantArray = $type->isConstantArray();
10651065
$isList = $type->isList();
1066+
$zeroOrMore = IntegerRangeType::fromInterval(0, null);
10661067
if (
10671068
!$isNormalCount->yes()
10681069
|| (!$isConstantArray->yes() && !$isList->yes())
10691070
|| $type->isIterableAtLeastOnce()->no() // array{} cannot be used for further narrowing
1071+
|| !$zeroOrMore->isSuperTypeOf($sizeType)->yes()
10701072
) {
10711073
return null;
10721074
}

tests/PHPStan/Analyser/nsrt/list-count.php

+44-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ protected function testOptionalKeysInUnionListWithIntRange($row, $twoOrThree, $t
369369
if (count($row) >= $maxThree) {
370370
assertType('array{string}|list{0: int, 1?: string|null, 2?: int|null, 3?: float|null}', $row);
371371
} else {
372-
assertType('list{0: int, 1?: string|null, 2?: int|null, 3?: float|null}', $row);
372+
assertType('array{string}|list{0: int, 1?: string|null, 2?: int|null, 3?: float|null}', $row);
373373
}
374374
}
375375

@@ -386,3 +386,46 @@ protected function testOptionalKeysInUnionArrayWithIntRange($row, $twoOrThree):
386386
}
387387
}
388388
}
389+
390+
class FooBug
391+
{
392+
public int $totalExpectedRows = 0;
393+
394+
/** @var list<\stdClass> */
395+
public array $importedDaySummaryRows = [];
396+
397+
public function sayHello(): void
398+
{
399+
assertType('int', $this->totalExpectedRows);
400+
assertType('list<stdClass>', $this->importedDaySummaryRows);
401+
if ($this->totalExpectedRows !== count($this->importedDaySummaryRows)) {
402+
assertType('int', $this->totalExpectedRows);
403+
assertType('list<stdClass>', $this->importedDaySummaryRows);
404+
}
405+
assertType('int', $this->totalExpectedRows);
406+
assertType('list<stdClass>', $this->importedDaySummaryRows);
407+
}
408+
}
409+
410+
class FooBugPositiveInt
411+
{
412+
/**
413+
* @var positive-int
414+
*/
415+
public int $totalExpectedRows = 1;
416+
417+
/** @var list<\stdClass> */
418+
public array $importedDaySummaryRows = [];
419+
420+
public function sayHello(): void
421+
{
422+
assertType('int<1, max>', $this->totalExpectedRows);
423+
assertType('list<stdClass>', $this->importedDaySummaryRows);
424+
if ($this->totalExpectedRows !== count($this->importedDaySummaryRows)) {
425+
assertType('int<1, max>', $this->totalExpectedRows);
426+
assertType('list<stdClass>', $this->importedDaySummaryRows);
427+
}
428+
assertType('int<1, max>', $this->totalExpectedRows);
429+
assertType('list<stdClass>', $this->importedDaySummaryRows);
430+
}
431+
}

0 commit comments

Comments
 (0)