From e0f3f8b442b6a9c9d9ffc515d5e8a7c4c2df50d0 Mon Sep 17 00:00:00 2001 From: Jack Worman Date: Tue, 21 May 2024 11:59:13 -0400 Subject: [PATCH] incompatible-binary-operands --- .../Expression/BinaryOpAnalyzer.php | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php index 1ec8d853aa2..bdaba9ccf42 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php @@ -32,6 +32,7 @@ use Psalm\Type\Atomic\TLiteralInt; use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Atomic\TNamedObject; +use Psalm\Type\Atomic\TObject; use Psalm\Type\Union; use UnexpectedValueException; @@ -247,8 +248,8 @@ public static function analyze( && $statements_analyzer->getCodebase()->config->strict_binary_operands && $stmt_left_type && $stmt_right_type - && !UnionTypeComparator::isContainedBy($codebase, $stmt_left_type, $stmt_right_type) - && !UnionTypeComparator::isContainedBy($codebase, $stmt_right_type, $stmt_left_type) + && (($stmt_left_type->isSingle() && $stmt_left_type->hasBool()) + || ($stmt_right_type->isSingle() && $stmt_right_type->hasBool())) ) { IssueBuffer::maybeAdd( new InvalidOperand( @@ -259,6 +260,35 @@ public static function analyze( ); } + + if ( + $stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal + || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotEqual + || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Greater + || $stmt instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual + || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Smaller + || $stmt instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual + && $statements_analyzer->getCodebase()->config->strict_binary_operands + && $stmt_left_type + && $stmt_right_type + ) { + if ( + ($stmt_left_type->hasObjectType() || $stmt_right_type->hasObjectType()) + && ( + !UnionTypeComparator::isContainedBy($codebase, $stmt_left_type, $stmt_right_type) + || !UnionTypeComparator::isContainedBy($codebase, $stmt_right_type, $stmt_left_type) + ) + ) { + IssueBuffer::maybeAdd( + new InvalidOperand( + 'Cannot compare ' . $stmt_left_type->getId() . ' to ' . $stmt_right_type->getId(), + new CodeLocation($statements_analyzer, $stmt), + ), + $statements_analyzer->getSuppressedIssues(), + ); + } + } + if (($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical