Skip to content

Commit 7a6a0fa

Browse files
authored
range() with float step should return an array of floats
1 parent 988f058 commit 7a6a0fa

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/Type/Php/RangeFunctionReturnTypeExtension.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,17 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
7979
}
8080

8181
if (count($rangeValues) > self::RANGE_LENGTH_THRESHOLD) {
82-
if ($startConstant instanceof ConstantIntegerType && $endConstant instanceof ConstantIntegerType) {
82+
if (
83+
$startConstant instanceof ConstantIntegerType
84+
&& $endConstant instanceof ConstantIntegerType
85+
&& $stepConstant instanceof ConstantIntegerType
86+
) {
8387
if ($startConstant->getValue() > $endConstant->getValue()) {
8488
$tmp = $startConstant;
8589
$startConstant = $endConstant;
8690
$endConstant = $tmp;
8791
}
92+
8893
return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(
8994
new ArrayType(
9095
new IntegerType(),
@@ -94,12 +99,23 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
9499
));
95100
}
96101

102+
if ($stepType->isFloat()->yes()) {
103+
return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(
104+
new ArrayType(
105+
new IntegerType(),
106+
new FloatType(),
107+
),
108+
new NonEmptyArrayType(),
109+
));
110+
}
111+
97112
return AccessoryArrayListType::intersectWith(TypeCombinator::intersect(
98113
new ArrayType(
99114
new IntegerType(),
100115
TypeCombinator::union(
101116
$startConstant->generalize(GeneralizePrecision::moreSpecific()),
102117
$endConstant->generalize(GeneralizePrecision::moreSpecific()),
118+
$stepType->generalize(GeneralizePrecision::moreSpecific()),
103119
),
104120
),
105121
new NonEmptyArrayType(),
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Bug11692;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/** @param int|float $floatOrInt */
8+
function doFoo(int $i, float $f, $floatOrInt): void {
9+
assertType('non-empty-list<float>', range(1, 9, .01));
10+
assertType('array{1, 4, 7}', range(1, 9, 3));
11+
12+
assertType('non-empty-list<float>', range(1, 9999, .01));
13+
assertType('non-empty-list<int<1, 9999>>', range(1, 9999, 3));
14+
15+
assertType('list<float|int>', range(1, 9999, $floatOrInt));
16+
assertType('list<float|int>', range(1, 9999, $floatOrInt));
17+
18+
assertType('list<int>', range(1, 3, $i));
19+
assertType('list<float|int>', range(1, 3, $f));
20+
21+
assertType('list<int>', range(1, 9999, $i));
22+
assertType('list<float|int>', range(1, 9999, $f));
23+
}
24+

0 commit comments

Comments
 (0)