Skip to content

Commit 746c5e5

Browse files
thg2kondrejmirtes
authored andcommitted
Fix division type result with even integer range
phpstan/phpstan#11175
1 parent dd534ea commit 746c5e5

File tree

2 files changed

+22
-24
lines changed

2 files changed

+22
-24
lines changed

src/Reflection/InitializerExprTypeResolver.php

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,31 +1760,25 @@ private function integerRangeMath(Type $range, BinaryOp $node, Type $operand): T
17601760
[$min, $max] = [$max, $min];
17611761
}
17621762

1763-
if ($operand instanceof IntegerRangeType
1764-
|| ($rangeMin === null || $rangeMax === null)
1765-
|| is_float($min)
1766-
|| is_float($max)
1767-
) {
1768-
if (is_float($min)) {
1769-
$min = (int) ceil($min);
1770-
}
1771-
if (is_float($max)) {
1772-
$max = (int) floor($max);
1773-
}
1774-
1775-
// invert maximas on division with negative constants
1776-
if ((($range instanceof ConstantIntegerType && $range->getValue() < 0)
1777-
|| ($operand instanceof ConstantIntegerType && $operand->getValue() < 0))
1778-
&& ($min === null || $max === null)) {
1779-
[$min, $max] = [$max, $min];
1780-
}
1763+
if (is_float($min)) {
1764+
$min = (int) ceil($min);
1765+
}
1766+
if (is_float($max)) {
1767+
$max = (int) floor($max);
1768+
}
17811769

1782-
if ($min === null && $max === null) {
1783-
return new BenevolentUnionType([new IntegerType(), new FloatType()]);
1784-
}
1770+
// invert maximas on division with negative constants
1771+
if ((($range instanceof ConstantIntegerType && $range->getValue() < 0)
1772+
|| ($operand instanceof ConstantIntegerType && $operand->getValue() < 0))
1773+
&& ($min === null || $max === null)) {
1774+
[$min, $max] = [$max, $min];
1775+
}
17851776

1786-
return TypeCombinator::union(IntegerRangeType::fromInterval($min, $max), new FloatType());
1777+
if ($min === null && $max === null) {
1778+
return new BenevolentUnionType([new IntegerType(), new FloatType()]);
17871779
}
1780+
1781+
return TypeCombinator::union(IntegerRangeType::fromInterval($min, $max), new FloatType());
17881782
} elseif ($node instanceof Expr\BinaryOp\ShiftLeft) {
17891783
if (!$operand instanceof ConstantIntegerType) {
17901784
return new IntegerType();

tests/PHPStan/Analyser/nsrt/integer-range-types.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,13 @@ public function math($i, $j, $z, $pi, $r1, $r2, $r3, $rMin, $rMax, $x, $y) {
288288
/**
289289
* @param int<0, max> $a
290290
* @param int<0, max> $b
291+
* @param int<16, 32> $c
292+
* @param int<2, 4> $d
291293
*/
292-
function divisionLoosesInformation(int $a, int $b): void {
293-
assertType('float|int<0, max>',$a/$b);
294+
function divisionLoosesInformation(int $a, int $b, int $c, int $d): void {
295+
assertType('float|int<0, max>', $a / $b);
296+
assertType('float|int<8, 16>', $c / 2);
297+
assertType('float|int<4, 16>', $c / $d);
294298
}
295299

296300
/**

0 commit comments

Comments
 (0)