From 2065e0129ecd496dccf7220f3acc415fd181bf76 Mon Sep 17 00:00:00 2001 From: Matthew Brown Date: Wed, 7 Nov 2018 08:45:26 -0500 Subject: [PATCH] Fix #1069 - module arithmetic always returns ints --- .../Statements/Expression/BinaryOpChecker.php | 20 ++++++++++++++----- tests/BinaryOperationTest.php | 19 ++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/Psalm/Checker/Statements/Expression/BinaryOpChecker.php b/src/Psalm/Checker/Statements/Expression/BinaryOpChecker.php index b80a62a5e..096966d8a 100644 --- a/src/Psalm/Checker/Statements/Expression/BinaryOpChecker.php +++ b/src/Psalm/Checker/Statements/Expression/BinaryOpChecker.php @@ -1011,7 +1011,9 @@ class BinaryOpChecker if (($left_type_part instanceof TNumeric || $right_type_part instanceof TNumeric) && ($left_type_part->isNumericType() && $right_type_part->isNumericType()) ) { - if (!$result_type) { + if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) { + $result_type = Type::getInt(); + } elseif (!$result_type) { $result_type = Type::getNumeric(); } else { $result_type = Type::combineUnionTypes(Type::getNumeric(), $result_type); @@ -1024,7 +1026,9 @@ class BinaryOpChecker } if ($left_type_part instanceof TInt && $right_type_part instanceof TInt) { - if (!$result_type) { + if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) { + $result_type = Type::getInt(); + } elseif (!$result_type) { $result_type = Type::getInt(true); } else { $result_type = Type::combineUnionTypes(Type::getInt(true), $result_type); @@ -1037,7 +1041,9 @@ class BinaryOpChecker } if ($left_type_part instanceof TFloat && $right_type_part instanceof TFloat) { - if (!$result_type) { + if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) { + $result_type = Type::getInt(); + } elseif (!$result_type) { $result_type = Type::getFloat(); } else { $result_type = Type::combineUnionTypes(Type::getFloat(), $result_type); @@ -1064,7 +1070,9 @@ class BinaryOpChecker } } - if (!$result_type) { + if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) { + $result_type = Type::getInt(); + } elseif (!$result_type) { $result_type = Type::getFloat(); } else { $result_type = Type::combineUnionTypes(Type::getFloat(), $result_type); @@ -1089,7 +1097,9 @@ class BinaryOpChecker } } - if (!$result_type) { + if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) { + $result_type = Type::getInt(); + } elseif (!$result_type) { $result_type = Type::getFloat(); } else { $result_type = Type::combineUnionTypes(Type::getFloat(), $result_type); diff --git a/tests/BinaryOperationTest.php b/tests/BinaryOperationTest.php index 6886ee250..1b0132a39 100644 --- a/tests/BinaryOperationTest.php +++ b/tests/BinaryOperationTest.php @@ -89,10 +89,29 @@ class BinaryOperationTest extends TestCase 'regularAddition' => [ ' [ + '$a' => 'int', + ], ], 'differingNumericTypesAdditionInWeakMode' => [ ' [ + '$a' => 'float', + ], + ], + 'modulo' => [ + ' [ + '$a' => 'int', + '$b' => 'int', + '$c' => 'int', + '$d' => 'int', + ], ], 'numericAddition' => [ '