Skip to content

Commit dd5633f

Browse files
committed
Fix isSmallerThan etc. in BenevolentUnionType
1 parent d9932a1 commit dd5633f

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

src/Type/UnionType.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -478,12 +478,12 @@ public function isCloneable(): TrinaryLogic
478478

479479
public function isSmallerThan(Type $otherType): TrinaryLogic
480480
{
481-
return $this->unionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType));
481+
return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType));
482482
}
483483

484484
public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic
485485
{
486-
return $this->unionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType));
486+
return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType));
487487
}
488488

489489
public function getSmallerType(): Type
@@ -508,12 +508,12 @@ public function getGreaterOrEqualType(): Type
508508

509509
public function isGreaterThan(Type $otherType): TrinaryLogic
510510
{
511-
return $this->unionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThan($type));
511+
return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThan($type));
512512
}
513513

514514
public function isGreaterThanOrEqual(Type $otherType): TrinaryLogic
515515
{
516-
return $this->unionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThanOrEqual($type));
516+
return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThanOrEqual($type));
517517
}
518518

519519
public function toBoolean(): BooleanType
@@ -668,6 +668,14 @@ protected function unionResults(callable $getResult): TrinaryLogic
668668
return TrinaryLogic::extremeIdentity(...array_map($getResult, $this->types));
669669
}
670670

671+
/**
672+
* @param callable(Type $type): TrinaryLogic $getResult
673+
*/
674+
private function notBenevolentUnionResults(callable $getResult): TrinaryLogic
675+
{
676+
return TrinaryLogic::extremeIdentity(...array_map($getResult, $this->types));
677+
}
678+
671679
/**
672680
* @param callable(Type $type): Type $getType
673681
*/

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ public function dataFileAsserts(): iterable
723723

724724
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6696.php');
725725
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Methods/data/filter-iterator-child-class.php');
726+
yield from $this->gatherAssertTypes(__DIR__ . '/data/smaller-than-benevolent.php');
726727
}
727728

728729
/**
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace SmallerThanBenevolent;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
10+
/**
11+
* @param int[] $a
12+
* @return void
13+
*/
14+
public function doFoo(array $a)
15+
{
16+
uksort($a, function ($x, $y): int {
17+
assertType('(int|string)', $x);
18+
assertType('(int|string)', $y);
19+
if ($x === 31 || $y === 31) {
20+
return 1;
21+
}
22+
23+
assertType('(int<min, 30>|int<32, max>|string)', $x);
24+
assertType('(int<min, 30>|int<32, max>|string)', $y);
25+
26+
assertType('bool', $x < $y);
27+
assertType('bool', $x <= $y);
28+
assertType('bool', $x > $y);
29+
assertType('bool', $x >= $y);
30+
31+
return $x < $y ? 1 : -1;
32+
});
33+
}
34+
35+
}

0 commit comments

Comments
 (0)