-
Notifications
You must be signed in to change notification settings - Fork 439
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
Fix variable certainty for ArrayDimFetch in falsey isset context #2666
Conversation
Please reproduce and fix the same problem with Empty_. |
hmm interessting.. it does not reproduce with |
1895cb1
to
595fc93
Compare
Ohh even more interessting.. it does not reproduce in a NodeScopeResolverTest, but running the same code directly with phpstan in a separate file reproduces the problem for |
fadf84f
to
32aefaa
Compare
ffe5f0a
to
e7c2382
Compare
after debugging deep in PHPStan internals, I think I am able to pinpoint the underlying issue. while handling while this process a variable which was "maybe" before automatically got a "yes"-certainty, because assigning a type to a variable automatically made it certain. I fixed this mechanism to also remember the previous certainty of the variable, not just the type and native-type. |
regarding build errors Carbon:
I think this error could be valid, as we are probably not narrow the type of the drupal
these look valid to me. it seems we are now detecting these mabye undefined while we were missing them before
also looks valid to me |
This pull request has been marked as ready for review. |
Did you look through the errors please? |
I did please see the comment above. I think our comments might be overlapped |
Sorry, if there are 21 emails in the thread, I tend to overlook things :) |
So if we're currently preserving the certainty, how does PHPStan go from "maybe" to "yes" in this case? // $foo is Maybe
if (isset($foo)) {
// $foo is Yes
} |
excellent question. I had to debug further and look into it even more to answer it ;-). we get from phpstan-src/src/Analyser/TypeSpecifier.php Line 748 in 6252d21
just pushed a new commit which refactors this code a bit to make it more obvious another interessting find: it seems we stop specifying types in |
$this->treatPhpDocTypesAsCertain = true; | ||
$this->strictUnnecessaryNullsafePropertyFetch = true; | ||
|
||
$this->analyse([__DIR__ . '/../../Analyser/data/bug-3985.php'], [ |
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.
I decided to add new assertions for this old bug, while in the process of understanding the internals better
(IMO the new assertions better describe what the end user expected)
Yeah, please clean this up as much as possible, and don't forget that both |
I'd still like to get from |
I see. do you talk about new features or something I need to make sure we don't regress? |
Not new features, but about this: https://phpstan.org/r/5f6093e0-0f6e-405a-9497-54263c6348b7 I worry that if you preserve certainty, there will be new error on line 12. |
should we not have the error on line 15 or should we have one on line8? |
We can't go from no to yes and from yes to no. |
Also an idea: in the other PR you introduced I think it should really be |
lets see if I understood you right ;)
I am fine with it. lets discuss it in the other PR when this one is merged |
5b5aa17
to
bbc692a
Compare
Thank you! Please continue by rebasing and finishing #2657. |
Hi @staabm this PR caused failures in Drupal and Carbon:
Fortunately it's not released yet. Please look into them otherwise I'll have to revert this. Thanks. |
I will have a look 👀 |
I had a first look into drupal problem - related source - and reduced it to: <?php
use function PHPStan\Testing\assertType;
use function PHPStan\Testing\assertVariableCertainty;
function book_node_links_alter():void {
if (isset($x)) {
$book_links = 1;
}
// Expected variable certainty Maybe, actual: No
assertVariableCertainty(\PHPStan\TrinaryLogic::createMaybe(), $book_links);
if (!empty($book_links)) {
var_dump($book_links);
}
} I wonder why we have a NO certainty here.. is it expected? |
another finding: in the latest 1.10 release in this snippet we went from No to Yes. function justEmpty(): void
{
assertVariableCertainty(TrinaryLogic::createNo(), $foo);
if (!empty($foo)) {
assertVariableCertainty(TrinaryLogic::createYes(), $foo);
}
assertVariableCertainty(TrinaryLogic::createNo(), $foo);
} this was changed with this PR here, but regressed the snippet in the above comment. |
to sum up my investigation of all mentioned failures caused by this PR: IMO there is only 1 regression, and thats the one reduced above. all remaining new failures are valid |
triggered by #2657 (comment)
btw: I realized that - across the PHPStan codebase - we are sometimes use
falsey
andfalsy
which is something we could fix with PHPStan 2.0