@@ -1982,7 +1982,7 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif
19821982 );
19831983 }
19841984
1985- if (!$ context ->null () && $ constantType ->getValue () === 0 && !$ otherType ->isInteger ()->yes ()) {
1985+ if (!$ context ->null () && $ constantType ->getValue () === 0 && !$ otherType ->isInteger ()->yes () && ! $ otherType -> isBoolean ()-> yes () ) {
19861986 /* There is a difference between php 7.x and 8.x on the equality
19871987 * behavior between zero and the empty string, so to be conservative
19881988 * we leave it untouched regardless of the language version */
@@ -2121,11 +2121,13 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif
21212121
21222122 public function resolveIdentical (Expr \BinaryOp \Identical $ expr , Scope $ scope , TypeSpecifierContext $ context , ?Expr $ rootExpr ): SpecifiedTypes
21232123 {
2124+ // Normalize to: fn() === expr
21242125 $ leftExpr = $ expr ->left ;
21252126 $ rightExpr = $ expr ->right ;
21262127 if ($ rightExpr instanceof FuncCall && !$ leftExpr instanceof FuncCall) {
21272128 [$ leftExpr , $ rightExpr ] = [$ rightExpr , $ leftExpr ];
21282129 }
2130+
21292131 $ unwrappedLeftExpr = $ leftExpr ;
21302132 if ($ leftExpr instanceof AlwaysRememberedExpr) {
21312133 $ unwrappedLeftExpr = $ leftExpr ->getExpr ();
@@ -2134,8 +2136,10 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
21342136 if ($ rightExpr instanceof AlwaysRememberedExpr) {
21352137 $ unwrappedRightExpr = $ rightExpr ->getExpr ();
21362138 }
2139+
21372140 $ rightType = $ scope ->getType ($ rightExpr );
21382141
2142+ // (count($a) === $b)
21392143 if (
21402144 !$ context ->null ()
21412145 && $ unwrappedLeftExpr instanceof FuncCall
@@ -2200,6 +2204,7 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
22002204 }
22012205 }
22022206
2207+ // strlen($a) === $b
22032208 if (
22042209 !$ context ->null ()
22052210 && $ unwrappedLeftExpr instanceof FuncCall
@@ -2236,6 +2241,7 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
22362241 }
22372242 }
22382243
2244+ // preg_match($a) === $b
22392245 if (
22402246 $ context ->true ()
22412247 && $ unwrappedLeftExpr instanceof FuncCall
@@ -2251,6 +2257,7 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
22512257 );
22522258 }
22532259
2260+ // get_class($a) === 'Foo'
22542261 if (
22552262 $ context ->true ()
22562263 && $ unwrappedLeftExpr instanceof FuncCall
@@ -2270,6 +2277,7 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
22702277 }
22712278 }
22722279
2280+ // get_class($a) === 'Foo'
22732281 if (
22742282 $ context ->truthy ()
22752283 && $ unwrappedLeftExpr instanceof FuncCall
@@ -2350,6 +2358,7 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
23502358 }
23512359 }
23522360
2361+ // $a::class === 'Foo'
23532362 if (
23542363 $ context ->true () &&
23552364 $ unwrappedLeftExpr instanceof ClassConstFetch &&
@@ -2372,6 +2381,8 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
23722381 }
23732382
23742383 $ leftType = $ scope ->getType ($ leftExpr );
2384+
2385+ // 'Foo' === $a::class
23752386 if (
23762387 $ context ->true () &&
23772388 $ unwrappedRightExpr instanceof ClassConstFetch &&
@@ -2417,7 +2428,11 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
24172428 $ types = null ;
24182429 if (
24192430 count ($ leftType ->getFiniteTypes ()) === 1
2420- || ($ context ->true () && $ leftType ->isConstantValue ()->yes () && !$ rightType ->equals ($ leftType ) && $ rightType ->isSuperTypeOf ($ leftType )->yes ())
2431+ || (
2432+ $ context ->true ()
2433+ && $ leftType ->isConstantValue ()->yes ()
2434+ && !$ rightType ->equals ($ leftType )
2435+ && $ rightType ->isSuperTypeOf ($ leftType )->yes ())
24212436 ) {
24222437 $ types = $ this ->create (
24232438 $ rightExpr ,
@@ -2440,7 +2455,12 @@ public function resolveIdentical(Expr\BinaryOp\Identical $expr, Scope $scope, Ty
24402455 }
24412456 if (
24422457 count ($ rightType ->getFiniteTypes ()) === 1
2443- || ($ context ->true () && $ rightType ->isConstantValue ()->yes () && !$ leftType ->equals ($ rightType ) && $ leftType ->isSuperTypeOf ($ rightType )->yes ())
2458+ || (
2459+ $ context ->true ()
2460+ && $ rightType ->isConstantValue ()->yes ()
2461+ && !$ leftType ->equals ($ rightType )
2462+ && $ leftType ->isSuperTypeOf ($ rightType )->yes ()
2463+ )
24442464 ) {
24452465 $ leftTypes = $ this ->create (
24462466 $ leftExpr ,
0 commit comments