diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index bd3021034a..ca120e1972 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -659,10 +659,15 @@ public function getBitwiseOrType(Expr $left, Expr $right, callable $getTypeCallb return new StringType(); } - if (TypeCombinator::union($leftType->toNumber(), $rightType->toNumber()) instanceof ErrorType) { + $unionType = TypeCombinator::union($leftType->toNumber(), $rightType->toNumber()); + if ($unionType instanceof ErrorType) { return new ErrorType(); } + if ($unionType->isInteger()->yes()) { + return $unionType; + } + return new IntegerType(); } diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index 2613002d0b..ab7af91e0d 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -1257,6 +1257,7 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/image-size.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/base64_decode.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9404.php'); + yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9384.php'); } /** diff --git a/tests/PHPStan/Analyser/data/bug-9384.php b/tests/PHPStan/Analyser/data/bug-9384.php new file mode 100644 index 0000000000..10ae51d521 --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-9384.php @@ -0,0 +1,22 @@ +|null */ + private static $type; + + public static function enableTrackingDeprecations(): void + { + assertType('int<0, 3>|null', self::$type); + assertType('1', self::TYPE_TRACK_DEPRECATIONS); + assertType('int<0, 3>', self::$type | self::TYPE_TRACK_DEPRECATIONS); + } +} diff --git a/tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php b/tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php index 2e8bb09784..1a7866536a 100644 --- a/tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php +++ b/tests/PHPStan/Rules/Properties/TypesAssignedToPropertiesRuleTest.php @@ -568,4 +568,15 @@ public function testWritingReadonlyProperty(): void ]); } + public function testBug9384(): void + { + $this->checkExplicitMixed = true; + $this->analyse([__DIR__ . '/data/bug-9384.php'], [ + [ + 'Static property Bug9384\Deprecation::$type (int<0, 3>|null) does not accept 10|int<0, 3>.', + 18, + ], + ]); + } + } diff --git a/tests/PHPStan/Rules/Properties/data/bug-9384.php b/tests/PHPStan/Rules/Properties/data/bug-9384.php new file mode 100644 index 0000000000..a4144ec481 --- /dev/null +++ b/tests/PHPStan/Rules/Properties/data/bug-9384.php @@ -0,0 +1,30 @@ +|null */ + private static $type; + + public static function enableTrackingDeprecations(): void + { + self::$type |= self::TYPE_TRACK_DEPRECATIONS; + + self::$type = self::$type | 10; // invalid value + } + + public static function enableWithTriggerError(): void + { + self::$type |= self::TYPE_TRIGGER_ERROR; + } + + public static function disable(): void + { + self::$type = self::TYPE_NONE; + } +}