Skip to content

Commit d22abbe

Browse files
committed
Fix ConstantArrayType::toBoolean()
1 parent 5452be5 commit d22abbe

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed

src/Type/Constant/ConstantArrayType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ public function slice(int $offset, ?int $limit, bool $preserveKeys = false): sel
602602

603603
public function toBoolean(): BooleanType
604604
{
605-
return new ConstantBooleanType(count($this->keyTypes) > 0);
605+
return $this->count()->toBoolean();
606606
}
607607

608608
public function generalize(): Type
@@ -690,7 +690,7 @@ public function count(): Type
690690
{
691691
$optionalKeysCount = count($this->optionalKeys);
692692
$totalKeysCount = count($this->getKeyTypes());
693-
if ($optionalKeysCount === $totalKeysCount) {
693+
if ($optionalKeysCount === 0) {
694694
return new ConstantIntegerType($totalKeysCount);
695695
}
696696

src/Type/IntegerRangeType.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type;
44

55
use PHPStan\TrinaryLogic;
6+
use PHPStan\Type\Constant\ConstantBooleanType;
67
use PHPStan\Type\Constant\ConstantIntegerType;
78

89
class IntegerRangeType extends IntegerType
@@ -152,6 +153,20 @@ public function toNumber(): Type
152153
return new parent();
153154
}
154155

156+
public function toBoolean(): BooleanType
157+
{
158+
$isZero = (new ConstantIntegerType(0))->isSuperTypeOf($this);
159+
if ($isZero->no()) {
160+
return new ConstantBooleanType(true);
161+
}
162+
163+
if ($isZero->maybe()) {
164+
return new BooleanType();
165+
}
166+
167+
return new ConstantBooleanType(false);
168+
}
169+
155170

156171
/**
157172
* @param mixed[] $properties

tests/PHPStan/Rules/Comparison/IfConstantConditionRuleTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,19 @@ public function testReportPhpDoc(): void
128128
]);
129129
}
130130

131+
public function testBug4043(): void
132+
{
133+
$this->treatPhpDocTypesAsCertain = true;
134+
$this->analyse([__DIR__ . '/data/bug-4043.php'], [
135+
[
136+
'If condition is always false.',
137+
43,
138+
],
139+
[
140+
'If condition is always true.',
141+
50,
142+
],
143+
]);
144+
}
145+
131146
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Bug4043;
4+
5+
function number(int $diff, string $s): string
6+
{
7+
8+
}
9+
10+
function (): void {
11+
$uppedDate = new \DateTime('now -1s');
12+
$diff = $uppedDate->diff(new \DateTime());
13+
assert($diff !== false);
14+
15+
$mdiff = (int)$diff->format('%m');
16+
$ddiff = (int)$diff->format('%d');
17+
$hdiff = (int)$diff->format('%H');
18+
$idiff = (int)$diff->format('%i');
19+
20+
$m = $mdiff ? number($mdiff, 'месяц|месяца|месяцев') : '';
21+
$d = $ddiff ? number($ddiff, 'день|дня|дней') : '';
22+
$h = $hdiff ? number($hdiff, 'час|часа|часов') : '';
23+
$i = $idiff ? number($idiff, 'минута|минуты|минут') : '';
24+
25+
$content = array_filter([$m, $d, $h, $i]);
26+
if ($content) {
27+
echo 1;
28+
}
29+
};
30+
31+
function (): void {
32+
$a = [];
33+
if (rand(0, 1)) {
34+
$a[] = 1;
35+
}
36+
if ($a) {
37+
38+
}
39+
};
40+
41+
function (): void {
42+
$a = [];
43+
if ($a) {
44+
45+
}
46+
};
47+
48+
function (): void {
49+
$a = [1];
50+
if ($a) {
51+
52+
}
53+
};

0 commit comments

Comments
 (0)