diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index 384b945d17..eae5158b7e 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -2594,8 +2594,11 @@ public function getBitwiseNotTypeFromType(Type $exprType): Type return TypeCombinator::intersect(...$accessories); } + if ($type instanceof ConstantIntegerType || $type instanceof ConstantFloatType) { + return new ConstantIntegerType(~ (int) $type->getValue()); + } if ($type->isInteger()->yes() || $type->isFloat()->yes()) { - return new IntegerType(); //no const types here, result depends on PHP_INT_SIZE + return new IntegerType(); } return new ErrorType(); }); diff --git a/tests/PHPStan/Analyser/Generator/data/gnsr.php b/tests/PHPStan/Analyser/Generator/data/gnsr.php index c6bddf33ff..99636621b2 100644 --- a/tests/PHPStan/Analyser/Generator/data/gnsr.php +++ b/tests/PHPStan/Analyser/Generator/data/gnsr.php @@ -96,8 +96,8 @@ public function doBitwiseNot($a, int $b): void { assertType('int', ~$a); assertNativeType('int', ~$b); - assertType('int', ~1); - assertNativeType('int', ~1); + assertType('-2', ~1); + assertNativeType('-2', ~1); assertType('int', ~$b); assertNativeType('int', ~$b); } diff --git a/tests/PHPStan/Analyser/nsrt/bitwise-not.php b/tests/PHPStan/Analyser/nsrt/bitwise-not.php index 37c29f8f97..01623d2d5b 100644 --- a/tests/PHPStan/Analyser/nsrt/bitwise-not.php +++ b/tests/PHPStan/Analyser/nsrt/bitwise-not.php @@ -17,5 +17,5 @@ function foo(int $int, string $string, float $float, $stringOrInt, string $nonEm assertType('int', ~$float); assertType('int|string', ~$stringOrInt); assertType("'" . (~"abc") . "'", ~"abc"); - assertType('int', ~1); //result is dependent on PHP_INT_SIZE + assertType('-2', ~1); }