66use PHPStan \Analyser \MutatingScope ;
77use PHPStan \Analyser \Scope ;
88use PHPStan \Node \Printer \ExprPrinter ;
9+ use PHPStan \Php \PhpVersion ;
910use PHPStan \Rules \Rule ;
1011use PHPStan \Rules \RuleErrorBuilder ;
1112use PHPStan \Rules \RuleLevelHelper ;
1213use PHPStan \ShouldNotHappenException ;
1314use PHPStan \TrinaryLogic ;
1415use PHPStan \Type \ErrorType ;
16+ use PHPStan \Type \ObjectType ;
1517use PHPStan \Type \Type ;
1618use PHPStan \Type \VerbosityLevel ;
1719use function sprintf ;
@@ -26,6 +28,7 @@ final class InvalidBinaryOperationRule implements Rule
2628
2729 public function __construct (
2830 private ExprPrinter $ exprPrinter ,
31+ private PhpVersion $ phpVersion ,
2932 private RuleLevelHelper $ ruleLevelHelper ,
3033 )
3134 {
@@ -70,9 +73,13 @@ public function processNode(Node $node, Scope $scope): array
7073 if ($ node instanceof Node \Expr \AssignOp \Concat || $ node instanceof Node \Expr \BinaryOp \Concat) {
7174 $ callback = static fn (Type $ type ): bool => !$ type ->toString () instanceof ErrorType;
7275 } elseif ($ node instanceof Node \Expr \AssignOp \Plus || $ node instanceof Node \Expr \BinaryOp \Plus) {
73- $ callback = static fn (Type $ type ): bool => !$ type ->toNumber () instanceof ErrorType || $ type ->isArray ()->yes ();
76+ $ callback = $ this ->phpVersion ->supportsBcMathNumberOperatorOverloading ()
77+ ? static fn (Type $ type ): bool => !$ type ->toNumber () instanceof ErrorType || $ type ->isArray ()->yes () || $ type ->isSuperTypeOf (new ObjectType ('BcMath\Number ' ))->yes ()
78+ : static fn (Type $ type ): bool => !$ type ->toNumber () instanceof ErrorType || $ type ->isArray ()->yes ();
7479 } else {
75- $ callback = static fn (Type $ type ): bool => !$ type ->toNumber () instanceof ErrorType;
80+ $ callback = $ this ->phpVersion ->supportsBcMathNumberOperatorOverloading ()
81+ ? static fn (Type $ type ): bool => !$ type ->toNumber () instanceof ErrorType || $ type ->isSuperTypeOf (new ObjectType ('BcMath\Number ' ))->yes ()
82+ : static fn (Type $ type ): bool => !$ type ->toNumber () instanceof ErrorType;
7683 }
7784
7885 $ leftType = $ this ->ruleLevelHelper ->findTypeToCheck (
0 commit comments