diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index b9e4415f99..17d05079dd 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -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(); diff --git a/tests/PHPStan/Analyser/nsrt/integer-range-types.php b/tests/PHPStan/Analyser/nsrt/integer-range-types.php index ffec07afdd..c769890c9e 100644 --- a/tests/PHPStan/Analyser/nsrt/integer-range-types.php +++ b/tests/PHPStan/Analyser/nsrt/integer-range-types.php @@ -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); } /**