Skip to content

Commit fb8e155

Browse files
committed
test different count() variants
1 parent e715e6a commit fb8e155

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

src/Analyser/LegacyTypeSpecifier.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
3939
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
4040
use PHPStan\Type\Accessory\HasOffsetType;
41+
use PHPStan\Type\Accessory\HasOffsetValueType;
4142
use PHPStan\Type\Accessory\HasPropertyType;
4243
use PHPStan\Type\Accessory\NonEmptyArrayType;
4344
use PHPStan\Type\ArrayType;
@@ -91,6 +92,7 @@
9192
#[AutowiredService(name: 'typeSpecifier', factory: '@typeSpecifierFactory::create', as: TypeSpecifier::class)]
9293
final class LegacyTypeSpecifier implements TypeSpecifier
9394
{
95+
private const MAX_ACCESSORIES_LIMIT = 8;
9496

9597
/** @var MethodTypeSpecifyingExtension[][]|null */
9698
private ?array $methodTypeSpecifyingExtensionsByClass = null;
@@ -1189,7 +1191,27 @@ private function specifyTypesForCountFuncCall(
11891191
$builderData[] = [$offsetType, $arrayType->getOffsetValueType($offsetType), !$hasOffset->yes()];
11901192
}
11911193
} else {
1192-
$resultTypes[] = TypeCombinator::intersect($arrayType, new NonEmptyArrayType());
1194+
$intersection = [];
1195+
$intersection[] = $arrayType;
1196+
$intersection[] = new NonEmptyArrayType();
1197+
1198+
$zero = new ConstantIntegerType(0);
1199+
$i = 0;
1200+
foreach ($builderData as [$offsetType, $valueType]) {
1201+
// non-empty-list already implies the offset 0
1202+
if ($zero->isSuperTypeOf($offsetType)->yes()) {
1203+
continue;
1204+
}
1205+
1206+
if ($i > self::MAX_ACCESSORIES_LIMIT) {
1207+
break;
1208+
}
1209+
1210+
$intersection[] = new HasOffsetValueType($offsetType, $valueType);
1211+
$i++;
1212+
}
1213+
1214+
$resultTypes[] = TypeCombinator::intersect(...$intersection);
11931215
continue;
11941216
}
11951217

tests/PHPStan/Analyser/nsrt/bug-13747.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ public function count($list): void
2323

2424
if (count($list, COUNT_NORMAL) > 2) {
2525
assertType('non-empty-list<int>&hasOffsetValue(1, int)&hasOffsetValue(2, int)', $list);
26-
assertType('int<3, max>', count($list));
26+
assertType('int<3, max>', count($list, COUNT_NORMAL));
2727
} else {
2828
assertType('non-empty-list<int>', $list);
2929
}
3030

3131
assertType('non-empty-list<int>', $list);
32-
if (count($list, COUNT_RECURSIVE) > 2) {
33-
assertType('non-empty-list<int>', $list);
34-
assertType('int<1, max>', count($list));
32+
if (count($list, COUNT_RECURSIVE) > 2) { // COUNT_RECURSIVE on non-recursive array
33+
assertType('non-empty-list<int>&hasOffsetValue(1, int)&hasOffsetValue(2, int)', $list);
34+
assertType('int<3, max>', count($list, COUNT_RECURSIVE));
3535
} else {
3636
assertType('non-empty-list<int>', $list);
3737
}

0 commit comments

Comments
 (0)