diff --git a/src/Type/UnionType.php b/src/Type/UnionType.php index 241fb0aa69..1a8ac35969 100644 --- a/src/Type/UnionType.php +++ b/src/Type/UnionType.php @@ -178,10 +178,6 @@ public function acceptsWithReason(Type $type, bool $strictTypes): AcceptsResult return AcceptsResult::createYes(); } - if ($type instanceof CompoundType && !$type instanceof CallableType && !$type instanceof TemplateType && !$type instanceof IntersectionType) { - return $type->isAcceptedWithReasonBy($this, $strictTypes); - } - $result = AcceptsResult::createNo(); foreach ($this->getSortedTypes() as $i => $innerType) { $result = $result->or($innerType->acceptsWithReason($type, $strictTypes)->decorateReasons(static fn (string $reason) => sprintf('Type #%d from the union: %s', $i + 1, $reason))); @@ -190,6 +186,10 @@ public function acceptsWithReason(Type $type, bool $strictTypes): AcceptsResult return $result; } + if ($type instanceof CompoundType && !$type instanceof CallableType && !$type instanceof TemplateType && !$type instanceof IntersectionType) { + return $type->isAcceptedWithReasonBy($this, $strictTypes); + } + if ($type instanceof TemplateUnionType) { return $result->or($type->isAcceptedWithReasonBy($this, $strictTypes)); } diff --git a/tests/PHPStan/Rules/Classes/InstantiationRuleTest.php b/tests/PHPStan/Rules/Classes/InstantiationRuleTest.php index ac43e1dc9c..36dc32c352 100644 --- a/tests/PHPStan/Rules/Classes/InstantiationRuleTest.php +++ b/tests/PHPStan/Rules/Classes/InstantiationRuleTest.php @@ -493,4 +493,14 @@ public function testPhpstanInternalClass(): void ]); } + public function testBug9659(): void + { + $this->analyse([__DIR__ . '/data/bug-9659.php'], []); + } + + public function testBug10248(): void + { + $this->analyse([__DIR__ . '/data/bug-10248.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Classes/data/bug-10248.php b/tests/PHPStan/Rules/Classes/data/bug-10248.php new file mode 100644 index 0000000000..ab21ff74b2 --- /dev/null +++ b/tests/PHPStan/Rules/Classes/data/bug-10248.php @@ -0,0 +1,31 @@ +=8.0 + +namespace Bug10248; + +class A { + public function __construct(DateTimeInterface|float $value) { + var_dump($value); + } +} + +class B { + public function __construct(float $value) { + var_dump($value); + } +} + +/** + * @return int + */ +function getInt(): int{return 1;} + +/** + * @return int<0, max> + */ +function getRangeInt(): int{return 1;} + +new A(123); +new A(getInt()); +new A(getRangeInt()); + +new B(getRangeInt()); diff --git a/tests/PHPStan/Rules/Classes/data/bug-9659.php b/tests/PHPStan/Rules/Classes/data/bug-9659.php new file mode 100644 index 0000000000..b78128fdca --- /dev/null +++ b/tests/PHPStan/Rules/Classes/data/bug-9659.php @@ -0,0 +1,17 @@ +=8.0 + +namespace Bug9659; + +class HelloWorld +{ + /** + * @param float|null $timeout + */ + public function __construct($timeout = null) + { + var_dump($timeout); + } +} + +new HelloWorld(20); // working +new HelloWorld(random_int(20, 80)); // broken