|
14 | 14 | use PHPStan\Type\ArrayType; |
15 | 15 | use PHPStan\Type\BenevolentUnionType; |
16 | 16 | use PHPStan\Type\Constant\ConstantArrayTypeBuilder; |
| 17 | +use PHPStan\Type\Constant\ConstantBooleanType; |
17 | 18 | use PHPStan\Type\Constant\ConstantFloatType; |
18 | 19 | use PHPStan\Type\Constant\ConstantIntegerType; |
19 | 20 | use PHPStan\Type\Constant\ConstantStringType; |
|
30 | 31 | use ValueError; |
31 | 32 | use function abs; |
32 | 33 | use function count; |
33 | | -use function is_array; |
34 | 34 | use function is_finite; |
35 | 35 | use function is_float; |
36 | 36 | use function is_string; |
@@ -93,14 +93,18 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, |
93 | 93 | try { |
94 | 94 | $rangeValues = @range($startConstant->getValue(), $endConstant->getValue(), $stepConstant->getValue()); |
95 | 95 | } catch (ValueError) { |
96 | | - if ($this->throwsOnAnalysedVersion($startConstant->getValue(), $endConstant->getValue(), $stepConstant->getValue())) { |
97 | | - $throwingCombinations++; |
98 | | - } |
99 | | - continue; |
| 96 | + $rangeValues = false; |
100 | 97 | } |
101 | 98 |
|
102 | | - // @phpstan-ignore function.alreadyNarrowedType |
103 | | - if (!is_array($rangeValues)) { |
| 99 | + // PHP 7 reports an invalid step by returning false instead of throwing a ValueError |
| 100 | + if ($rangeValues === false) { |
| 101 | + if ($this->failsOnAnalysedVersion($startConstant->getValue(), $endConstant->getValue(), $stepConstant->getValue())) { |
| 102 | + if ($this->phpVersion->throwsValueErrorForInternalFunctions()) { |
| 103 | + $throwingCombinations++; |
| 104 | + } else { |
| 105 | + $constantReturnTypes[] = new ConstantBooleanType(false); |
| 106 | + } |
| 107 | + } |
104 | 108 | continue; |
105 | 109 | } |
106 | 110 |
|
@@ -193,15 +197,11 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection, |
193 | 197 |
|
194 | 198 | /** |
195 | 199 | * The constant arguments are folded by calling range() on the PHP version PHPStan |
196 | | - * itself runs on, so a ValueError only says that the runtime rejects the step. |
197 | | - * The analysed PHP version is consulted separately before it is turned into never. |
| 200 | + * itself runs on, so a failure only says that the runtime rejects the step. |
| 201 | + * This checks whether the analysed PHP version rejects it as well. |
198 | 202 | */ |
199 | | - private function throwsOnAnalysedVersion(int|float|string $start, int|float|string $end, int|float $step): bool |
| 203 | + private function failsOnAnalysedVersion(int|float|string $start, int|float|string $end, int|float $step): bool |
200 | 204 | { |
201 | | - if (!$this->phpVersion->throwsValueErrorForInternalFunctions()) { |
202 | | - return false; |
203 | | - } |
204 | | - |
205 | 205 | if ($this->phpVersion->hasStricterRangeFunction()) { |
206 | 206 | return true; |
207 | 207 | } |
|
0 commit comments