Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b482a5b

Browse files
authored
Subtract zero-float when comparing against zero-int
1 parent a7188ef commit b482a5b

File tree

6 files changed

+100
-7
lines changed

6 files changed

+100
-7
lines changed

‎src/Type/Traits/ConstantNumericComparisonTypeTrait.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Type\Traits;
44

55
use PHPStan\Type\Constant\ConstantBooleanType;
6+
use PHPStan\Type\Constant\ConstantFloatType;
67
use PHPStan\Type\IntegerRangeType;
78
use PHPStan\Type\MixedType;
89
use PHPStan\Type\NullType;
@@ -22,6 +23,7 @@ public function getSmallerType(): Type
2223
if (!(bool) $this->value) {
2324
$subtractedTypes[] = new NullType();
2425
$subtractedTypes[] = new ConstantBooleanType(false);
26+
$subtractedTypes[] = new ConstantFloatType(0.0); // subtract range when we support float-ranges
2527
}
2628

2729
return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes));
@@ -31,6 +33,7 @@ public function getSmallerOrEqualType(): Type
3133
{
3234
$subtractedTypes = [
3335
IntegerRangeType::createAllGreaterThan($this->value),
36+
// subtract range when we support float-ranges
3437
];
3538

3639
if (!(bool) $this->value) {
@@ -45,6 +48,7 @@ public function getGreaterType(): Type
4548
$subtractedTypes = [
4649
new NullType(),
4750
new ConstantBooleanType(false),
51+
new ConstantFloatType(0.0), // subtract range when we support float-ranges
4852
IntegerRangeType::createAllSmallerThanOrEqualTo($this->value),
4953
];
5054

@@ -64,6 +68,7 @@ public function getGreaterOrEqualType(): Type
6468
if ((bool) $this->value) {
6569
$subtractedTypes[] = new NullType();
6670
$subtractedTypes[] = new ConstantBooleanType(false);
71+
$subtractedTypes[] = new ConstantFloatType(0.0); // subtract range when we support float-ranges
6772
}
6873

6974
return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes));

‎tests/PHPStan/Analyser/NodeScopeResolverTest.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,7 @@ public function dataFileAsserts(): iterable
14891489
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10468.php');
14901490
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6613.php');
14911491
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10187.php');
1492+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5309.php');
14921493
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10834.php');
14931494
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-11035.php');
14941495
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-10952.php');

‎tests/PHPStan/Analyser/TypeSpecifierTest.php‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ public function dataCondition(): iterable
822822
'$n' => 'mixed~int<3, max>|true',
823823
],
824824
[
825-
'$n' => 'mixed~int<min, 2>|false|null',
825+
'$n' => 'mixed~0.0|int<min, 2>|false|null',
826826
],
827827
],
828828
[
@@ -834,7 +834,7 @@ public function dataCondition(): iterable
834834
'$n' => 'mixed~int<' . PHP_INT_MIN . ', max>|true',
835835
],
836836
[
837-
'$n' => 'mixed~false|null',
837+
'$n' => 'mixed~0.0|false|null',
838838
],
839839
],
840840
[
@@ -843,7 +843,7 @@ public function dataCondition(): iterable
843843
new LNumber(PHP_INT_MAX),
844844
),
845845
[
846-
'$n' => 'mixed~bool|int<min, ' . PHP_INT_MAX . '>|null',
846+
'$n' => 'mixed~0.0|bool|int<min, ' . PHP_INT_MAX . '>|null',
847847
],
848848
[
849849
'$n' => 'mixed',
@@ -858,7 +858,7 @@ public function dataCondition(): iterable
858858
'$n' => 'mixed~int<' . (PHP_INT_MIN + 1) . ', max>',
859859
],
860860
[
861-
'$n' => 'mixed~bool|int<min, ' . PHP_INT_MIN . '>|null',
861+
'$n' => 'mixed~0.0|bool|int<min, ' . PHP_INT_MIN . '>|null',
862862
],
863863
],
864864
[
@@ -867,7 +867,7 @@ public function dataCondition(): iterable
867867
new LNumber(PHP_INT_MAX),
868868
),
869869
[
870-
'$n' => 'mixed~int<min, ' . (PHP_INT_MAX - 1) . '>|false|null',
870+
'$n' => 'mixed~0.0|int<min, ' . (PHP_INT_MAX - 1) . '>|false|null',
871871
],
872872
[
873873
'$n' => 'mixed~int<' . PHP_INT_MAX . ', max>|true',
@@ -885,7 +885,7 @@ public function dataCondition(): iterable
885885
),
886886
),
887887
[
888-
'$n' => 'mixed~int<min, 2>|int<6, max>|false|null',
888+
'$n' => 'mixed~0.0|int<min, 2>|int<6, max>|false|null',
889889
],
890890
[
891891
'$n' => 'mixed~int<3, 5>|true',
@@ -1250,7 +1250,7 @@ public function dataCondition(): iterable
12501250
),
12511251
[
12521252
'$foo' => 'non-empty-array',
1253-
'count($foo)' => 'mixed~int<min, 1>|false|null',
1253+
'count($foo)' => 'mixed~0.0|int<min, 1>|false|null',
12541254
],
12551255
[],
12561256
],
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
namespace Bug5309;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function greater(float $y): float {
8+
$x = 0.0;
9+
if($y > 0) {
10+
$x += 1;
11+
}
12+
assertType('0.0|1.0', $x);
13+
if($x > 0) {
14+
assertType('1.0', $x);
15+
return 5 / $x;
16+
}
17+
assertType('0.0|1.0', $x); // could be '0.0' when we support float-ranges
18+
19+
return 1.0;
20+
}
21+
22+
function greaterEqual(float $y): float {
23+
$x = 0.0;
24+
if($y > 0) {
25+
$x += 1;
26+
}
27+
assertType('0.0|1.0', $x);
28+
if($x >= 0) {
29+
assertType('0.0|1.0', $x);
30+
return 5 / $x;
31+
}
32+
assertType('0.0|1.0', $x); // could be '*NEVER*' when we support float-ranges
33+
34+
return 1.0;
35+
}
36+
37+
function smaller(float $y): float {
38+
$x = 0.0;
39+
if($y > 0) {
40+
$x -= 1;
41+
}
42+
assertType('-1.0|0.0', $x);
43+
if($x < 0) {
44+
assertType('-1.0', $x);
45+
return 5 / $x;
46+
}
47+
assertType('-1.0|0.0', $x); // could be '0.0' when we support float-ranges
48+
49+
return 1.0;
50+
}
51+
52+
function smallerEqual(float $y): float {
53+
$x = 0.0;
54+
if($y > 0) {
55+
$x -= 1;
56+
}
57+
assertType('-1.0|0.0', $x);
58+
if($x <= 0) {
59+
assertType('-1.0|0.0', $x);
60+
return 5 / $x;
61+
}
62+
assertType('*NEVER*', $x);
63+
64+
return 1.0;
65+
}

‎tests/PHPStan/Rules/Operators/InvalidBinaryOperationRuleTest.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,4 +278,9 @@ public function testRuleWithNullsafeVariant(): void
278278
]);
279279
}
280280

281+
public function testBug5309(): void
282+
{
283+
$this->analyse([__DIR__ . '/data/bug-5309.php'], []);
284+
}
285+
281286
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Bug5309;
4+
5+
function sayHello(float $y): float
6+
{
7+
$x = 0.0;
8+
if ($y > 0) {
9+
$x += 1;
10+
}
11+
if ($x > 0) {
12+
return 5 / $x;
13+
}
14+
15+
return 1.0;
16+
}
17+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /