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
Transform void
return to null
after call
#2778
Transform void
return to null
after call
#2778
Conversation
I think the problem with existing rules might not be that hard to fix. Most of the failures are from the error that's supposed to be reported here: phpstan-src/src/Rules/FunctionCallParametersCheck.php Lines 233 to 241 in 3c7860c
We could for example clone the node and add an attribute like |
I had a similar thought. Basically, we'd need to either a) keep the information somewhere that this was a void before, either e.g. in the type or the node as you said or b) modify the void type to behave more like null, since it's a special return-only type it always means that it must have came from a return. I guess the "remember in node" approach is the cleanest and one that makes most sense :) I also quickly checked psalm yesterday and looks like it's transforming void to null too basically. |
hmm, this keeps being tricky, I tried to clone the node in rules and add an attribute as you suggested. problem: there were cases where the type was already resolved and it would get it from the internal cache via key again. this could also be circumvented I guess? it's a bit unfortunate hmm. |
@herndlm Change the cache key based on the attribute in |
b51abd9
to
7dbe5a8
Compare
src/Analyser/MutatingScope.php
Outdated
@@ -674,6 +674,10 @@ private function getNodeKey(Expr $node): string | |||
$key .= '/*' . $node->getAttribute('startFilePos') . '*/'; | |||
} | |||
|
|||
if ($node->hasAttribute('keepVoid')) { |
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.
would be great if we could put this string into a class-constant somewhere.
that way it would ease navigation with the IDE and make dependent parts obvious
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.
yeah, I wanted to check first if all is fine and then ask about how to properly refactor this thing
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.
Could be a new method on Scope, just don't start it with getType
, I'd hate to confuse autocompletion with this niche use case
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.
still need to do this refactor, missed the comment. currently working on it
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.
looks like I'm prone to commenting race conditions today.. :) did something, not sure about the name of course. this is now in Scope after all and should be stable. WDYT?
got it working, this is looking not bad, did only quickly go through the failures, the ones that worry me
|
Stop early in the callback: if ($type instanceof CallableType || $type instanceof ClosureType) {
return $type;
} About simplify - don't worry about it, they'll have to fix their code. |
symplify/symplify is abandoned. parts of it moved to symplify/phpstan-rules |
I've update the tests in phpstan/phpstan to symplify/phpstan-rules, you can try again :) |
sorry, still trying to recreate one of the failures of PMMP to properly test the fix.. class Bar
{
/** @phpstan-param \Closure(): void $handler */
public function doFoo(\Closure $handler): void
{
\PHPStan\dumpType($handler()); // void
\PHPStan\dumpType($this->handler()); // null
}
public function doBar(): void
{
$handler = $this->handler(...);
\PHPStan\dumpType($handler); // Closure(): void
$this->doFoo($handler);
}
private function handler(): void
{
}
} is working just fine in an AnalyserIntegrationTest which I don't understand. I tried to replicate the CI failure I saw via https://github.com/pmmp/PocketMine-MP/blob/0984aa670d5c04e4714853dbf738f51bfa4f39e1/src/network/mcpe/handler/SessionStartPacketHandler.php#L39 and https://github.com/pmmp/PocketMine-MP/blob/0984aa670d5c04e4714853dbf738f51bfa4f39e1/src/network/mcpe/NetworkSession.php#L201 but I can of course just try to adapt the traverse callback 😅 |
This passes on 1.10.x but fails on your PR: https://phpstan.org/r/f8d2decc-2d58-4ce4-a2b3-d811700abe9f |
I'd say we need to do the same phpstan-src/src/Analyser/MutatingScope.php Lines 1230 to 1233 in 7e7cc9c
|
bingo! thx again :) what do you think about the previous code example I pasted, it looks like those closure returns are not transformed to null yet. I guess that could be fixed? |
That's okay and actually correct behaviour. We don't want to transform Your TypeTransformer callback only transforms standalone |
42d4d9f
to
edf2ead
Compare
sorry for the many force pushes, should be good now. do you not think we should refactor it somehow? e.g. put the |
This pull request has been marked as ready for review. |
Please see #2778 (comment) |
23bfd2e
to
14871cd
Compare
Thank you! |
@herndlm Can you please look at this bug? https://github.com/WordPress/WordPress-Coding-Standards/pull/2416/files We should allow returning |
I dislike those WP void unions.. but sure. https://phpstan.org/r/12a90bd8-64db-4620-855c-23579d0085f6 seems to be a simple reproducer too. |
@@ -1236,7 +1242,7 @@ private function resolveType(string $exprString, Expr $node): Type | |||
new VoidType(), | |||
]); | |||
} else { | |||
$returnType = $arrowScope->getType($node->expr); | |||
$returnType = $arrowScope->getKeepVoidType($node->expr); |
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.
does it make sense to handle a "void" return type of a arrow function? can arrow functions have a void return type?
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.
Try to change it and see what fails. I think it's valid, at least for a throw expr or calling never function.
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.
just found #2778 (comment) which answers this question, I guess
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.
hmm locally I did not get a test failure after changing it. lets see #2873
Closes phpstan/phpstan#6720
What I meant with question marks yesterday
UsageOfVoidMatchExpressionRule
seems to be not doing anything anymore I guessAlso thought of: only transform void in union/intersection types, but that does feel inconsistent..
WDYT?