From 8266b305ace6ba225d56c79fea27b87a6264171a Mon Sep 17 00:00:00 2001 From: Kevin van Sonsbeek Date: Fri, 7 Feb 2025 19:33:41 +0100 Subject: [PATCH 1/4] bugfix(#11241): Add test cases for addition and subtraction --- tests/BinaryOperationTest.php | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/BinaryOperationTest.php b/tests/BinaryOperationTest.php index 5ecc5533326..13a995e4f8e 100644 --- a/tests/BinaryOperationTest.php +++ b/tests/BinaryOperationTest.php @@ -592,6 +592,44 @@ function scope(){ '$b' => 'float', ], ], + 'intArithmeticAssignmentAdditionFromFunction' => [ + 'code' => ' [ + '$a===' => 'int', + ], + ], + 'intArithmeticAssignmentAddition' => [ + 'code' => ' [ + '$a===' => '6', + ], + ], + 'intArithmeticAssignmentSubtractionFromFunction' => [ + 'code' => ' [ + '$a===' => 'int', + ], + ], + 'intArithmeticAssignmentSubtraction' => [ + 'code' => ' [ + '$a===' => '3', + ], + ], 'exponent' => [ 'code' => ' Date: Fri, 7 Feb 2025 20:42:18 +0100 Subject: [PATCH 2/4] bugfix(#11241): Set type to TInt if the VirtualPlus or VirtualMinus is performed in the context of an assignment --- .../Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php index 10d14b45f18..387cf93ba41 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php @@ -831,7 +831,11 @@ private static function analyzeOperands( $new_type = new TIntRange(null, $left_type_part->value + $sum); } } elseif ($left_type_part instanceof TLiteralInt) { - $new_type = new TLiteralInt($left_type_part->value + $sum); + if ($context->inside_assignment) { + $new_type = new TInt(); + } else { + $new_type = new TLiteralInt($left_type_part->value + $sum); + } } elseif ($left_type_part instanceof TIntRange) { $start = $left_type_part->min_bound === null ? null : $left_type_part->min_bound + $sum; $end = $left_type_part->max_bound === null ? null : $left_type_part->max_bound + $sum; From e7b79b56e918242ac99689e3ed678414ea53aacf Mon Sep 17 00:00:00 2001 From: Kevin van Sonsbeek Date: Fri, 7 Feb 2025 21:04:24 +0100 Subject: [PATCH 3/4] bugfix(#11241): Add missing check to see if context is set --- .../Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php index 387cf93ba41..264fb7c9003 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php @@ -831,7 +831,7 @@ private static function analyzeOperands( $new_type = new TIntRange(null, $left_type_part->value + $sum); } } elseif ($left_type_part instanceof TLiteralInt) { - if ($context->inside_assignment) { + if ($context && $context->inside_assignment) { $new_type = new TInt(); } else { $new_type = new TLiteralInt($left_type_part->value + $sum); From 9b6734d0729b0216491d54c4fb914e319fc5cfd9 Mon Sep 17 00:00:00 2001 From: Kevin van Sonsbeek Date: Mon, 10 Feb 2025 17:42:54 +0100 Subject: [PATCH 4/4] bugfix(#11241): Add comment --- .../Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php index 264fb7c9003..4d87d3749d3 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php @@ -823,6 +823,8 @@ private static function analyzeOperands( } } } elseif ($parent instanceof VirtualPlus || $parent instanceof VirtualMinus) { + // This seems arbitrary defined as 1/-1, to facilitate loops + // and may need a better handling if there's issues $sum = $parent instanceof VirtualPlus ? 1 : -1; if ($context && $context->inside_loop && $left_type_part instanceof TLiteralInt) { if ($parent instanceof VirtualPlus) {