Skip to content

Commit 7b1f9bb

Browse files
committed
fix
1 parent 00e1f1b commit 7b1f9bb

File tree

3 files changed

+110
-5
lines changed

3 files changed

+110
-5
lines changed

src/Type/ArrayType.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
371371
new NullType(),
372372
new IntegerType(),
373373
new FloatType(),
374+
new NeverType()
374375
]);
375376

376377
if ($looseFalse->isSuperTypeOf($type)->yes()) {

src/Type/CallableType.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
use PHPStan\Reflection\ParametersAcceptor;
1111
use PHPStan\ShouldNotHappenException;
1212
use PHPStan\TrinaryLogic;
13+
use PHPStan\Type\Constant\ConstantArrayType;
1314
use PHPStan\Type\Constant\ConstantBooleanType;
15+
use PHPStan\Type\Constant\ConstantFloatType;
16+
use PHPStan\Type\Constant\ConstantIntegerType;
17+
use PHPStan\Type\Constant\ConstantStringType;
1418
use PHPStan\Type\Generic\TemplateType;
1519
use PHPStan\Type\Generic\TemplateTypeHelper;
1620
use PHPStan\Type\Generic\TemplateTypeMap;
@@ -426,7 +430,29 @@ public function isScalar(): TrinaryLogic
426430

427431
public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
428432
{
429-
if ($type->isObject()->yes()) {
433+
$looseTrue = new UnionType([
434+
new ConstantBooleanType(true),
435+
new ConstantIntegerType(1),
436+
]);
437+
438+
if ($looseTrue->isSuperTypeOf($type)->yes()) {
439+
return new ConstantBooleanType(true);
440+
}
441+
442+
$looseFalse = new UnionType([
443+
new NullType(),
444+
new ObjectWithoutClassType(),
445+
new ConstantStringType(''),
446+
new ConstantBooleanType(false),
447+
new FloatType(),
448+
new IntegerType(),
449+
new NeverType(),
450+
]);
451+
452+
if ($looseFalse->isSuperTypeOf($type)->yes()
453+
|| $type->isConstantArray()->yes() && $type->isIterableAtLeastOnce()->no()
454+
|| $type->isNumericString()->yes()
455+
) {
430456
return new ConstantBooleanType(false);
431457
}
432458

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

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace LooseSemantics;
66

7+
use function PHPStan\dumpType;
78
use function PHPStan\Testing\assertType;
89

910
class HelloWorld
@@ -929,7 +930,6 @@ public function looseString(
929930
}
930931

931932
/**
932-
* @param never $never
933933
* @param true $true
934934
* @param false $false
935935
* @param 1 $one
@@ -950,7 +950,6 @@ public function looseString(
950950
* https://3v4l.org/RHc0P
951951
*/
952952
public function looseNever(
953-
$never,
954953
$true,
955954
$false,
956955
$one,
@@ -973,6 +972,7 @@ public function looseNever(
973972
$unionNumbers,
974973
$unionStrings
975974
) {
975+
$never = $this->returnNever();
976976
assertType('false', $never == $true);
977977
assertType('false', $never == $false);
978978
assertType('false', $never == $one);
@@ -1001,6 +1001,11 @@ public function looseNever(
10011001
assertType('false', $never == $unionStrings);
10021002
}
10031003

1004+
/** @return never */
1005+
function returnNever() {
1006+
exit();
1007+
}
1008+
10041009
/**
10051010
* @param never $never
10061011
* @param true $true
@@ -1024,7 +1029,6 @@ public function looseNever(
10241029
* https://3v4l.org/RHc0P
10251030
*/
10261031
public function looseArray(
1027-
$never,
10281032
$true,
10291033
$false,
10301034
$one,
@@ -1048,7 +1052,6 @@ public function looseArray(
10481052
$unionStrings,
10491053
$unionMaybeArray
10501054
) {
1051-
assertType('false', $arr == $never);
10521055
assertType('true', $arr == $true);
10531056
assertType('false', $arr == $false);
10541057
assertType('false', $arr == $one);
@@ -1076,4 +1079,79 @@ public function looseArray(
10761079
assertType('false', $arr == $unionStrings);
10771080
assertType('bool', $arr == $unionMaybeArray);
10781081
}
1082+
1083+
/**
1084+
* @param callable $callable
1085+
* @param true $true
1086+
* @param false $false
1087+
* @param 1 $one
1088+
* @param 0 $zero
1089+
* @param -1 $minusOne
1090+
* @param '1' $oneStr
1091+
* @param '0' $zeroStr
1092+
* @param '-1' $minusOneStr
1093+
* @param null $null
1094+
* @param array{} $emptyArr
1095+
* @param 'php' $phpStr
1096+
* @param '' $emptyStr
1097+
* @param array $arr
1098+
* @param 'a'|'123'|'123.23' $unionMaybeNumeric
1099+
* @param 1|2|3 $unionNumbers
1100+
* @param 'a'|'b'|'c' $unionStrings
1101+
* @param 'a'|'123'|123|array $unionMaybeArray
1102+
*
1103+
* https://3v4l.org/RHc0P
1104+
*/
1105+
public function looseCallable(
1106+
$callable,
1107+
$true,
1108+
$false,
1109+
$one,
1110+
$zero,
1111+
$minusOne,
1112+
$oneStr,
1113+
$zeroStr,
1114+
$minusOneStr,
1115+
$null,
1116+
$emptyArr,
1117+
$phpStr,
1118+
$emptyStr,
1119+
array $arr,
1120+
int $int,
1121+
float $float,
1122+
bool $bool,
1123+
string $string,
1124+
object $obj,
1125+
$unionMaybeNumeric,
1126+
$unionNumbers,
1127+
$unionStrings,
1128+
$unionMaybeArray
1129+
) {
1130+
assertType('true', $callable == $true);
1131+
assertType('false', $callable == $false);
1132+
assertType('true', $callable == $one);
1133+
assertType('false', $callable == $zero);
1134+
assertType('false', $callable == 10);
1135+
assertType('false', $callable == $minusOne);
1136+
assertType('false', $callable == $oneStr);
1137+
assertType('false', $callable == $zeroStr);
1138+
assertType('false', $callable == $minusOneStr);
1139+
assertType('false', $callable == $null);
1140+
assertType('false', $callable == $emptyArr);
1141+
assertType('bool', $callable == $phpStr);
1142+
assertType('false', $callable == $emptyStr);
1143+
assertType('false', $callable == $float);
1144+
assertType('false', $callable == []);
1145+
assertType('bool', $callable == $arr);
1146+
assertType('false', $callable == $int);
1147+
assertType('false', $callable == $float);
1148+
assertType('bool', $callable == $bool);
1149+
assertType('bool', $callable == $string);
1150+
assertType('false', $callable == $obj);
1151+
assertType('false', $callable == new \stdClass());
1152+
assertType('bool', $callable == $unionMaybeNumeric);
1153+
assertType('false', $callable == $unionNumbers);
1154+
assertType('bool', $callable == $unionStrings);
1155+
assertType('bool', $callable == $unionMaybeArray);
1156+
}
10791157
}

0 commit comments

Comments
 (0)