-
Notifications
You must be signed in to change notification settings - Fork 429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Solve https://github.com/phpstan/phpstan/issues/5348 #586
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
use PHPStan\Type\TypeCombinator; | ||
use PHPStan\Type\TypeUtils; | ||
use PHPStan\Type\UnionType; | ||
use PHPStan\Type\VerbosityLevel; | ||
|
||
class RuleLevelHelper | ||
{ | ||
|
@@ -76,6 +77,14 @@ public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTyp | |
} | ||
|
||
if ($acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) { | ||
if ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi, I don't see why RuleLevelHelper would have to be changed for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't know why but there is an early check here: When I check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue is about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. acceptingType = DateTime|DateTimeImmutable
We're in this if. So we're currently doing
and since neither DateTime doesn't accept DateTimeInterface, neither DateTimeImmutable accept DateTimeInterface, false is returned. I can change the check
to something like
if you prefer, but something has to be done here. If I remove the code added here, tests are failing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WDYT @ondrejmirtes ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The change in RuleLevelHelper shouldn't be specific to the DateTime situation, but more general. I propose something like this: diff --git a/src/Rules/RuleLevelHelper.php b/src/Rules/RuleLevelHelper.php
index 240258921..7fc9724b8 100644
--- a/src/Rules/RuleLevelHelper.php
+++ b/src/Rules/RuleLevelHelper.php
@@ -75,7 +75,8 @@ class RuleLevelHelper
$acceptedType = TypeCombinator::removeNull($acceptedType);
}
- if ($acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) {
+ $accepts = $acceptingType->accepts($acceptedType, $strictTypes);
+ if (!$accepts->yes() && $acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) {
foreach ($acceptingType->getTypes() as $innerType) {
if (self::accepts($innerType, $acceptedType, $strictTypes)) {
return true;
@@ -103,8 +104,6 @@ class RuleLevelHelper
);
}
- $accepts = $acceptingType->accepts($acceptedType, $strictTypes);
-
return $this->checkUnionTypes ? $accepts->yes() : !$accepts->no();
}
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I didn't like to be specific to the DateTime but It wasn't clear to me what to do. I used your proposal and seems to work perfectly ; thanks :) |
||
$acceptedType->describe(VerbosityLevel::precise()) === 'DateTimeInterface' | ||
&& str_contains($acceptingType->describe(VerbosityLevel::precise()), 'DateTime|DateTimeImmutable') | ||
) { | ||
return true; | ||
} | ||
|
||
|
||
foreach ($acceptingType->getTypes() as $innerType) { | ||
if (self::accepts($innerType, $acceptedType, $strictTypes)) { | ||
return true; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
class HelloWorld | ||
{ | ||
/** | ||
* @param \DateTime|\DateTimeImmutable|int $date | ||
*/ | ||
public function sayHello($date): void | ||
{ | ||
} | ||
|
||
/** | ||
* @param \DateTimeInterface|int $d | ||
*/ | ||
public function foo($d): void | ||
{ | ||
$this->sayHello($d); | ||
} | ||
} | ||
|
||
class HelloWorld2 | ||
{ | ||
/** | ||
* @param \DateTime|\DateTimeImmutable $date | ||
*/ | ||
public function sayHello($date): void | ||
{ | ||
} | ||
|
||
/** | ||
* @param \DateTimeInterface $d | ||
*/ | ||
public function foo($d): void | ||
{ | ||
$this->sayHello($d); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For local test