Skip to content

Commit

Permalink
Fix division type result with even integer range
Browse files Browse the repository at this point in the history
  • Loading branch information
thg2k authored and ondrejmirtes committed Jun 15, 2024
1 parent dd534ea commit 746c5e5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 24 deletions.
38 changes: 16 additions & 22 deletions src/Reflection/InitializerExprTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1760,31 +1760,25 @@ private function integerRangeMath(Type $range, BinaryOp $node, Type $operand): T
[$min, $max] = [$max, $min];
}

if ($operand instanceof IntegerRangeType
|| ($rangeMin === null || $rangeMax === null)
|| is_float($min)
|| is_float($max)
) {
if (is_float($min)) {
$min = (int) ceil($min);
}
if (is_float($max)) {
$max = (int) floor($max);
}

// invert maximas on division with negative constants
if ((($range instanceof ConstantIntegerType && $range->getValue() < 0)
|| ($operand instanceof ConstantIntegerType && $operand->getValue() < 0))
&& ($min === null || $max === null)) {
[$min, $max] = [$max, $min];
}
if (is_float($min)) {
$min = (int) ceil($min);
}
if (is_float($max)) {
$max = (int) floor($max);
}

if ($min === null && $max === null) {
return new BenevolentUnionType([new IntegerType(), new FloatType()]);
}
// invert maximas on division with negative constants
if ((($range instanceof ConstantIntegerType && $range->getValue() < 0)
|| ($operand instanceof ConstantIntegerType && $operand->getValue() < 0))
&& ($min === null || $max === null)) {
[$min, $max] = [$max, $min];
}

return TypeCombinator::union(IntegerRangeType::fromInterval($min, $max), new FloatType());
if ($min === null && $max === null) {
return new BenevolentUnionType([new IntegerType(), new FloatType()]);
}

return TypeCombinator::union(IntegerRangeType::fromInterval($min, $max), new FloatType());
} elseif ($node instanceof Expr\BinaryOp\ShiftLeft) {
if (!$operand instanceof ConstantIntegerType) {
return new IntegerType();
Expand Down
8 changes: 6 additions & 2 deletions tests/PHPStan/Analyser/nsrt/integer-range-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,13 @@ public function math($i, $j, $z, $pi, $r1, $r2, $r3, $rMin, $rMax, $x, $y) {
/**
* @param int<0, max> $a
* @param int<0, max> $b
* @param int<16, 32> $c
* @param int<2, 4> $d
*/
function divisionLoosesInformation(int $a, int $b): void {
assertType('float|int<0, max>',$a/$b);
function divisionLoosesInformation(int $a, int $b, int $c, int $d): void {
assertType('float|int<0, max>', $a / $b);
assertType('float|int<8, 16>', $c / 2);
assertType('float|int<4, 16>', $c / $d);
}

/**
Expand Down

0 comments on commit 746c5e5

Please sign in to comment.