@@ -1611,7 +1611,7 @@ private function processBooleanNotSureConditionalTypes(Scope $scope, SpecifiedTy
16111611 }
16121612
16131613 /**
1614- * @return array{Expr, ConstantScalarType}|null
1614+ * @return array{Expr, ConstantScalarType, Type }|null
16151615 */
16161616 private function findTypeExpressionsFromBinaryOperation (Scope $ scope , Node \Expr \BinaryOp $ binaryOperation ): ?array
16171617 {
@@ -1633,13 +1633,13 @@ private function findTypeExpressionsFromBinaryOperation(Scope $scope, Node\Expr\
16331633 && !$ rightExpr instanceof ConstFetch
16341634 && !$ rightExpr instanceof ClassConstFetch
16351635 ) {
1636- return [$ binaryOperation ->right , $ leftType ];
1636+ return [$ binaryOperation ->right , $ leftType, $ rightType ];
16371637 } elseif (
16381638 $ rightType instanceof ConstantScalarType
16391639 && !$ leftExpr instanceof ConstFetch
16401640 && !$ leftExpr instanceof ClassConstFetch
16411641 ) {
1642- return [$ binaryOperation ->left , $ rightType ];
1642+ return [$ binaryOperation ->left , $ rightType, $ leftType ];
16431643 }
16441644
16451645 return null ;
@@ -1950,6 +1950,7 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif
19501950 if ($ expressions !== null ) {
19511951 $ exprNode = $ expressions [0 ];
19521952 $ constantType = $ expressions [1 ];
1953+ $ otherType = $ expressions [2 ];
19531954
19541955 if (!$ context ->null () && $ constantType ->getValue () === null ) {
19551956 $ trueTypes = [
@@ -1981,6 +1982,30 @@ public function resolveEqual(Expr\BinaryOp\Equal $expr, Scope $scope, TypeSpecif
19811982 );
19821983 }
19831984
1985+ if (!$ context ->null () && $ constantType ->getValue () === 0 && !$ otherType ->isInteger ()->yes ()) {
1986+ /* There is a difference between php 7.x and 8.x on the equality
1987+ * behavior between zero and the empty string, so to be conservative
1988+ * we leave it untouched regardless of the language version */
1989+ if ($ context ->true ()) {
1990+ $ trueTypes = [
1991+ new NullType (),
1992+ new ConstantBooleanType (false ),
1993+ new ConstantIntegerType (0 ),
1994+ new ConstantFloatType (0.0 ),
1995+ new StringType (),
1996+ ];
1997+ } else {
1998+ $ trueTypes = [
1999+ new NullType (),
2000+ new ConstantBooleanType (false ),
2001+ new ConstantIntegerType (0 ),
2002+ new ConstantFloatType (0.0 ),
2003+ new ConstantStringType ('0 ' ),
2004+ ];
2005+ }
2006+ return $ this ->create ($ exprNode , new UnionType ($ trueTypes ), $ context , false , $ scope , $ rootExpr );
2007+ }
2008+
19842009 if (!$ context ->null () && $ constantType ->getValue () === '' ) {
19852010 /* There is a difference between php 7.x and 8.x on the equality
19862011 * behavior between zero and the empty string, so to be conservative
0 commit comments