Skip to content

Commit 9867a23

Browse files
committed
Improve inference on FuncCall === FuncCall
1 parent ffe6337 commit 9867a23

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,6 +2241,25 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif
22412241
}
22422242

22432243
public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes
2244+
{
2245+
$specifiedTypes = $this->resolveNormalizedIdentical($expr, $scope, $context);
2246+
2247+
// merge result of fn1() === fn2() and fn2() === fn1()
2248+
$leftExpr = $expr->left;
2249+
$rightExpr = $expr->right;
2250+
if ($rightExpr instanceof FuncCall && $leftExpr instanceof FuncCall) {
2251+
return $specifiedTypes->unionWith(
2252+
$this->resolveNormalizedIdentical(new Expr\BinaryOp\Identical(
2253+
$rightExpr,
2254+
$leftExpr,
2255+
), $scope, $context),
2256+
);
2257+
}
2258+
2259+
return $specifiedTypes;
2260+
}
2261+
2262+
private function resolveNormalizedIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes
22442263
{
22452264
// Normalize to: fn() === expr
22462265
$leftExpr = $expr->left;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug13749;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class HelloWorld
8+
{
9+
/**
10+
* @param non-empty-string $nonES
11+
*/
12+
public function sayNonEmpty(string $s, string $nonES): void
13+
{
14+
if (strlen($nonES) === strlen($s)) {
15+
assertType('non-empty-string', $s);
16+
}
17+
if (strlen($nonES) >= strlen($s)) {
18+
assertType('string', $s); // could be non-empty-string
19+
}
20+
21+
if (strlen($s) === strlen($nonES)) {
22+
assertType('non-empty-string', $s);
23+
}
24+
if (strlen($s) >= strlen($nonES)) {
25+
assertType('non-empty-string', $s);
26+
}
27+
}
28+
29+
/**
30+
* @param non-falsy-string $nonFalsy
31+
*/
32+
public function sayNonFalsy(string $s, string $nonFalsy): void
33+
{
34+
if (strlen($nonFalsy) === strlen($s)) {
35+
assertType('non-empty-string', $s);
36+
}
37+
if (strlen($nonFalsy) >= strlen($s)) {
38+
assertType('string', $s); // could be non-empty-string
39+
}
40+
41+
if (strlen($s) === strlen($nonFalsy)) {
42+
assertType('non-empty-string', $s);
43+
}
44+
if (strlen($s) >= strlen($nonFalsy)) {
45+
assertType('non-empty-string', $s);
46+
}
47+
}
48+
49+
}

0 commit comments

Comments
 (0)