Skip to content

Commit f3d449f

Browse files
DateTime|DateTimeInterface union accepts DateTimeInterface
1 parent 419bc0d commit f3d449f

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

src/Rules/RuleLevelHelper.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTyp
7575
$acceptedType = TypeCombinator::removeNull($acceptedType);
7676
}
7777

78-
if ($acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) {
78+
$accepts = $acceptingType->accepts($acceptedType, $strictTypes);
79+
if (!$accepts->yes() && $acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) {
7980
foreach ($acceptingType->getTypes() as $innerType) {
8081
if (self::accepts($innerType, $acceptedType, $strictTypes)) {
8182
return true;
@@ -103,8 +104,6 @@ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTyp
103104
);
104105
}
105106

106-
$accepts = $acceptingType->accepts($acceptedType, $strictTypes);
107-
108107
return $this->checkUnionTypes ? $accepts->yes() : !$accepts->no();
109108
}
110109

src/Type/UnionType.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ public function getReferencedClasses(): array
7070

7171
public function accepts(Type $type, bool $strictTypes): TrinaryLogic
7272
{
73+
if (
74+
$type->equals(new ObjectType(\DateTimeInterface::class))
75+
&& $this->accepts(
76+
new UnionType([new ObjectType(\DateTime::class), new ObjectType(\DateTimeImmutable::class)]),
77+
$strictTypes
78+
)->yes()
79+
) {
80+
return TrinaryLogic::createYes();
81+
}
82+
7383
if ($type instanceof CompoundType && !$type instanceof CallableType) {
7484
return CompoundTypeHelper::accepts($type, $this, $strictTypes);
7585
}

tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,10 @@ public function testCallMethods(): void
493493
'Parameter #1 $test of method Test\NumericStringParam::sayHello() expects string&numeric, \'abc\' given.',
494494
1658,
495495
],
496+
[
497+
'Parameter #1 $date of method Test\HelloWorld3::sayHello() expects array<DateTime|DateTimeImmutable>|int, DateTimeInterface given.',
498+
1732,
499+
],
496500
]);
497501
}
498502

@@ -767,6 +771,10 @@ public function testCallMethodsOnThisOnly(): void
767771
'Parameter #1 $test of method Test\NumericStringParam::sayHello() expects string&numeric, \'abc\' given.',
768772
1658,
769773
],
774+
[
775+
'Parameter #1 $date of method Test\HelloWorld3::sayHello() expects array<DateTime|DateTimeImmutable>|int, DateTimeInterface given.',
776+
1732,
777+
],
770778
]);
771779
}
772780

tests/PHPStan/Rules/Methods/data/call-methods.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,3 +1678,57 @@ public function openStatically(): void
16781678
}
16791679

16801680
}
1681+
1682+
class HelloWorld
1683+
{
1684+
/**
1685+
* @param \DateTime|\DateTimeImmutable|int $date
1686+
*/
1687+
public function sayHello($date): void
1688+
{
1689+
}
1690+
1691+
/**
1692+
* @param \DateTimeInterface|int $d
1693+
*/
1694+
public function foo($d): void
1695+
{
1696+
$this->sayHello($d);
1697+
}
1698+
}
1699+
1700+
class HelloWorld2
1701+
{
1702+
/**
1703+
* @param \DateTime|\DateTimeImmutable $date
1704+
*/
1705+
public function sayHello($date): void
1706+
{
1707+
}
1708+
1709+
/**
1710+
* @param \DateTimeInterface $d
1711+
*/
1712+
public function foo($d): void
1713+
{
1714+
$this->sayHello($d);
1715+
}
1716+
}
1717+
1718+
class HelloWorld3
1719+
{
1720+
/**
1721+
* @param array<\DateTime|\DateTimeImmutable>|int $date
1722+
*/
1723+
public function sayHello($date): void
1724+
{
1725+
}
1726+
1727+
/**
1728+
* @param \DateTimeInterface $d
1729+
*/
1730+
public function foo($d): void
1731+
{
1732+
$this->sayHello($d);
1733+
}
1734+
}

0 commit comments

Comments
 (0)