diff --git a/README.md b/README.md
index 85b9a5ab..e56aa34d 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
|:---------------------------------------|:--------------------------------------------------------------------------------------------------------|
| `booleansInConditions` | Require booleans in `if`, `elseif`, ternary operator, after `!`, and on both sides of `&&` and `\|\|`. |
| `booleansInLoopConditions` | Require booleans in `while` and `do while` loop conditions. |
-| `numericOperandsInArithmeticOperators` | Require numeric operands or arrays in `+` and numeric operands in `-`/`*`/`/`/`**`/`%`. |
+| `numericOperandsInArithmeticOperators` | Require numeric operand in `+$var`, `-$var`, `$var++`, `$var--`, `++$var` and `--$var`. |
| `numericOperandsInArithmeticOperators` | Require numeric operand in `$var++`, `$var--`, `++$var`and `--$var`. |
| `strictFunctionCalls` | These functions contain a `$strict` parameter for better type safety, it must be set to `true`:
* `in_array` (3rd parameter)
* `array_search` (3rd parameter)
* `array_keys` (3rd parameter; only if the 2nd parameter `$search_value` is provided)
* `base64_decode` (2nd parameter). |
| `overwriteVariablesWithLoop` | Variables assigned in `while` loop condition and `for` loop initial assignment cannot be used after the loop. |
diff --git a/rules.neon b/rules.neon
index dd20b8d1..7a63c4ec 100644
--- a/rules.neon
+++ b/rules.neon
@@ -106,6 +106,10 @@ conditionalTags:
phpstan.rules.rule: %strictRules.numericOperandsInArithmeticOperators%
PHPStan\Rules\Operators\OperandInArithmeticPreIncrementRule:
phpstan.rules.rule: %strictRules.numericOperandsInArithmeticOperators%
+ PHPStan\Rules\Operators\OperandInArithmeticUnaryMinusRule:
+ phpstan.rules.rule: [%strictRules.numericOperandsInArithmeticOperators%, %featureToggles.bleedingEdge%]
+ PHPStan\Rules\Operators\OperandInArithmeticUnaryPlusRule:
+ phpstan.rules.rule: [%strictRules.numericOperandsInArithmeticOperators%, %featureToggles.bleedingEdge%]
PHPStan\Rules\Operators\OperandsInArithmeticAdditionRule:
phpstan.rules.rule: %strictRules.numericOperandsInArithmeticOperators%
PHPStan\Rules\Operators\OperandsInArithmeticDivisionRule:
@@ -242,6 +246,12 @@ services:
-
class: PHPStan\Rules\Operators\OperandInArithmeticPreIncrementRule
+ -
+ class: PHPStan\Rules\Operators\OperandInArithmeticUnaryMinusRule
+
+ -
+ class: PHPStan\Rules\Operators\OperandInArithmeticUnaryPlusRule
+
-
class: PHPStan\Rules\Operators\OperandsInArithmeticAdditionRule
diff --git a/src/Rules/Operators/OperandInArithmeticUnaryMinusRule.php b/src/Rules/Operators/OperandInArithmeticUnaryMinusRule.php
new file mode 100644
index 00000000..d3db7df5
--- /dev/null
+++ b/src/Rules/Operators/OperandInArithmeticUnaryMinusRule.php
@@ -0,0 +1,47 @@
+
+ */
+class OperandInArithmeticUnaryMinusRule implements Rule
+{
+
+ private OperatorRuleHelper $helper;
+
+ public function __construct(OperatorRuleHelper $helper)
+ {
+ $this->helper = $helper;
+ }
+
+ public function getNodeType(): string
+ {
+ return UnaryMinus::class;
+ }
+
+ public function processNode(Node $node, Scope $scope): array
+ {
+ $messages = [];
+
+ if (!$this->helper->isValidForArithmeticOperation($scope, $node->expr)) {
+ $varType = $scope->getType($node->expr);
+
+ $messages[] = RuleErrorBuilder::message(sprintf(
+ 'Only numeric types are allowed in unary -, %s given.',
+ $varType->describe(VerbosityLevel::typeOnly()),
+ ))->identifier('unaryMinus.nonNumeric')->build();
+ }
+
+ return $messages;
+ }
+
+}
diff --git a/src/Rules/Operators/OperandInArithmeticUnaryPlusRule.php b/src/Rules/Operators/OperandInArithmeticUnaryPlusRule.php
new file mode 100644
index 00000000..78313d8c
--- /dev/null
+++ b/src/Rules/Operators/OperandInArithmeticUnaryPlusRule.php
@@ -0,0 +1,47 @@
+
+ */
+class OperandInArithmeticUnaryPlusRule implements Rule
+{
+
+ private OperatorRuleHelper $helper;
+
+ public function __construct(OperatorRuleHelper $helper)
+ {
+ $this->helper = $helper;
+ }
+
+ public function getNodeType(): string
+ {
+ return UnaryPlus::class;
+ }
+
+ public function processNode(Node $node, Scope $scope): array
+ {
+ $messages = [];
+
+ if (!$this->helper->isValidForArithmeticOperation($scope, $node->expr)) {
+ $varType = $scope->getType($node->expr);
+
+ $messages[] = RuleErrorBuilder::message(sprintf(
+ 'Only numeric types are allowed in unary +, %s given.',
+ $varType->describe(VerbosityLevel::typeOnly()),
+ ))->identifier('unaryPlus.nonNumeric')->build();
+ }
+
+ return $messages;
+ }
+
+}
diff --git a/tests/Rules/Operators/OperandInArithmeticUnaryMinusRuleTest.php b/tests/Rules/Operators/OperandInArithmeticUnaryMinusRuleTest.php
new file mode 100644
index 00000000..d202bdbc
--- /dev/null
+++ b/tests/Rules/Operators/OperandInArithmeticUnaryMinusRuleTest.php
@@ -0,0 +1,34 @@
+
+ */
+class OperandInArithmeticUnaryMinusRuleTest extends RuleTestCase
+{
+
+ protected function getRule(): Rule
+ {
+ return new OperandInArithmeticUnaryMinusRule(
+ new OperatorRuleHelper(
+ self::getContainer()->getByType(RuleLevelHelper::class),
+ ),
+ );
+ }
+
+ public function testRule(): void
+ {
+ $this->analyse([__DIR__ . '/data/operators.php'], [
+ [
+ 'Only numeric types are allowed in unary -, null given.',
+ 233,
+ ],
+ ]);
+ }
+
+}
diff --git a/tests/Rules/Operators/OperandInArithmeticUnaryPlusRuleTest.php b/tests/Rules/Operators/OperandInArithmeticUnaryPlusRuleTest.php
new file mode 100644
index 00000000..6cc253a3
--- /dev/null
+++ b/tests/Rules/Operators/OperandInArithmeticUnaryPlusRuleTest.php
@@ -0,0 +1,34 @@
+
+ */
+class OperandInArithmeticUnaryPlusRuleTest extends RuleTestCase
+{
+
+ protected function getRule(): Rule
+ {
+ return new OperandInArithmeticUnaryPlusRule(
+ new OperatorRuleHelper(
+ self::getContainer()->getByType(RuleLevelHelper::class),
+ ),
+ );
+ }
+
+ public function testRule(): void
+ {
+ $this->analyse([__DIR__ . '/data/operators.php'], [
+ [
+ 'Only numeric types are allowed in unary +, null given.',
+ 225,
+ ],
+ ]);
+ }
+
+}
diff --git a/tests/Rules/Operators/data/operators.php b/tests/Rules/Operators/data/operators.php
index f3e75598..0c230064 100644
--- a/tests/Rules/Operators/data/operators.php
+++ b/tests/Rules/Operators/data/operators.php
@@ -215,3 +215,19 @@ function (array $array, int $int, $mixed) {
/** @var numeric-string $numericString */
$numericString = doFoo();
$numericString += 1;
+
++$int;
++$float;
++$intOrFloat;
++$string;
++$array;
++$object;
++$null;
+
+-$int;
+-$float;
+-$intOrFloat;
+-$string;
+-$array;
+-$object;
+-$null;