Skip to content

Commit

Permalink
Fix isSmallerThan etc. in BenevolentUnionType
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Feb 27, 2022
1 parent d9932a1 commit dd5633f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/Type/UnionType.php
Expand Up @@ -478,12 +478,12 @@ public function isCloneable(): TrinaryLogic

public function isSmallerThan(Type $otherType): TrinaryLogic
{
return $this->unionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType));
return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType));
}

public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic
{
return $this->unionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType));
return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType));
}

public function getSmallerType(): Type
Expand All @@ -508,12 +508,12 @@ public function getGreaterOrEqualType(): Type

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

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

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

/**
* @param callable(Type $type): TrinaryLogic $getResult
*/
private function notBenevolentUnionResults(callable $getResult): TrinaryLogic
{
return TrinaryLogic::extremeIdentity(...array_map($getResult, $this->types));
}

/**
* @param callable(Type $type): Type $getType
*/
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Expand Up @@ -723,6 +723,7 @@ public function dataFileAsserts(): iterable

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

/**
Expand Down
35 changes: 35 additions & 0 deletions tests/PHPStan/Analyser/data/smaller-than-benevolent.php
@@ -0,0 +1,35 @@
<?php

namespace SmallerThanBenevolent;

use function PHPStan\Testing\assertType;

class Foo
{

/**
* @param int[] $a
* @return void
*/
public function doFoo(array $a)
{
uksort($a, function ($x, $y): int {
assertType('(int|string)', $x);
assertType('(int|string)', $y);
if ($x === 31 || $y === 31) {
return 1;
}

assertType('(int<min, 30>|int<32, max>|string)', $x);
assertType('(int<min, 30>|int<32, max>|string)', $y);

assertType('bool', $x < $y);
assertType('bool', $x <= $y);
assertType('bool', $x > $y);
assertType('bool', $x >= $y);

return $x < $y ? 1 : -1;
});
}

}

0 comments on commit dd5633f

Please sign in to comment.