Skip to content

Commit 702b082

Browse files
committed
Improve loose comparison on constant types
1 parent 9f78100 commit 702b082

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

src/Type/Constant/ConstantArrayType.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,18 @@ public function isSuperTypeOf(Type $type): IsSuperTypeOfResult
418418

419419
public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
420420
{
421-
if ($this->isIterableAtLeastOnce()->no() && count($type->getConstantScalarValues()) === 1) {
422-
// @phpstan-ignore equal.invalid, equal.notAllowed
423-
return new ConstantBooleanType($type->getConstantScalarValues()[0] == []); // phpcs:ignore
421+
if ($type->isInteger()->yes()) {
422+
return new ConstantBooleanType(false);
423+
}
424+
425+
if ($this->isIterableAtLeastOnce()->no()) {
426+
if (count($type->getConstantScalarValues()) === 1) {
427+
// @phpstan-ignore equal.invalid, equal.notAllowed
428+
return new ConstantBooleanType($type->getConstantScalarValues()[0] == []); // phpcs:ignore
429+
}
430+
if ($type->isIterableAtLeastOnce()->yes()) {
431+
return new ConstantBooleanType(false);
432+
}
424433
}
425434

426435
return new BooleanType();

tests/PHPStan/Analyser/nsrt/loose-comparisons.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,8 @@ public function sayInt(
633633
array $array,
634634
int $int,
635635
int $intRange,
636+
string $emptyStr,
637+
string $phpStr,
636638
): void
637639
{
638640
assertType('bool', $int == $true);
@@ -651,6 +653,20 @@ public function sayInt(
651653
assertType('false', $intRange == $emptyArr);
652654
assertType('false', $intRange == $array);
653655

656+
assertType('false', 5 == $emptyArr);
657+
assertType('false', $emptyArr == 5);
658+
assertType('false', 5 == $array);
659+
assertType('false', $array == 5);
660+
assertType('false', [] == 5);
661+
assertType('false', 5 == []);
662+
663+
assertType('false', 5 == $emptyStr);
664+
assertType('false', 5 == $phpStr);
665+
assertType('false', 5 == 'a');
666+
667+
assertType('false', $emptyStr == 5);
668+
assertType('false', $phpStr == 5);
669+
assertType('false', 'a' == 5);
654670
}
655671

656672
/**
@@ -703,6 +719,7 @@ public function sayConstUnion(
703719
* @param lowercase-string $lower
704720
* @param array{} $emptyArr
705721
* @param non-empty-array $nonEmptyArr
722+
* @param array{abc: string, num?: int, nullable: ?string} $arrShape
706723
* @param int<10, 20> $intRange
707724
*/
708725
public function sayIntersection(
@@ -712,6 +729,7 @@ public function sayIntersection(
712729
array $emptyArr,
713730
array $nonEmptyArr,
714731
array $arr,
732+
array $arrShape,
715733
int $i,
716734
int $intRange,
717735
): void
@@ -743,10 +761,18 @@ public function sayIntersection(
743761
assertType('false', $nonEmptyArr == $i);
744762
assertType('false', $arr == $intRange);
745763
assertType('false', $nonEmptyArr == $intRange);
746-
assertType('bool', $emptyArr == $nonEmptyArr); // should be false
764+
assertType('false', $emptyArr == $nonEmptyArr);
747765
assertType('false', $nonEmptyArr == $emptyArr);
748766
assertType('bool', $arr == $nonEmptyArr);
749767
assertType('bool', $nonEmptyArr == $arr);
768+
assertType('false', 5 == $arr);
769+
assertType('false', $arr == 5);
770+
assertType('false', 5 == $emptyArr);
771+
assertType('false', $emptyArr == 5);
772+
assertType('false', 5 == $nonEmptyArr);
773+
assertType('false', $nonEmptyArr == 5);
774+
assertType('false', 5 == $arrShape);
775+
assertType('false', $arrShape == 5);
750776

751777
assertType('bool', '' == $lower);
752778
if ($lower != '') {

0 commit comments

Comments
 (0)