Skip to content

Commit 6c2edd5

Browse files
Fix union with float should accept integer range
1 parent 52d6a89 commit 6c2edd5

File tree

4 files changed

+62
-4
lines changed

4 files changed

+62
-4
lines changed

src/Type/UnionType.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,6 @@ public function acceptsWithReason(Type $type, bool $strictTypes): AcceptsResult
178178
return AcceptsResult::createYes();
179179
}
180180

181-
if ($type instanceof CompoundType && !$type instanceof CallableType && !$type instanceof TemplateType && !$type instanceof IntersectionType) {
182-
return $type->isAcceptedWithReasonBy($this, $strictTypes);
183-
}
184-
185181
$result = AcceptsResult::createNo();
186182
foreach ($this->getSortedTypes() as $i => $innerType) {
187183
$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
190186
return $result;
191187
}
192188

189+
if ($type instanceof CompoundType && !$type instanceof CallableType && !$type instanceof TemplateType && !$type instanceof IntersectionType) {
190+
return $type->isAcceptedWithReasonBy($this, $strictTypes);
191+
}
192+
193193
if ($type instanceof TemplateUnionType) {
194194
return $result->or($type->isAcceptedWithReasonBy($this, $strictTypes));
195195
}

tests/PHPStan/Rules/Classes/InstantiationRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,4 +493,14 @@ public function testPhpstanInternalClass(): void
493493
]);
494494
}
495495

496+
public function testBug9659(): void
497+
{
498+
$this->analyse([__DIR__ . '/data/bug-9659.php'], []);
499+
}
500+
501+
public function testBug10248(): void
502+
{
503+
$this->analyse([__DIR__ . '/data/bug-10248.php'], []);
504+
}
505+
496506
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php // lint >=8.0
2+
3+
namespace Bug10248;
4+
5+
class A {
6+
public function __construct(DateTimeInterface|float $value) {
7+
var_dump($value);
8+
}
9+
}
10+
11+
class B {
12+
public function __construct(float $value) {
13+
var_dump($value);
14+
}
15+
}
16+
17+
/**
18+
* @return int
19+
*/
20+
function getInt(): int{return 1;}
21+
22+
/**
23+
* @return int<0, max>
24+
*/
25+
function getRangeInt(): int{return 1;}
26+
27+
new A(123);
28+
new A(getInt());
29+
new A(getRangeInt());
30+
31+
new B(getRangeInt());
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php // lint >=8.0
2+
3+
namespace Bug9659;
4+
5+
class HelloWorld
6+
{
7+
/**
8+
* @param float|null $timeout
9+
*/
10+
public function __construct($timeout = null)
11+
{
12+
var_dump($timeout);
13+
}
14+
}
15+
16+
new HelloWorld(20); // working
17+
new HelloWorld(random_int(20, 80)); // broken

0 commit comments

Comments
 (0)