-
Notifications
You must be signed in to change notification settings - Fork 483
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 false positives on non-existing-offset's #3766
base: 2.1.x
Are you sure you want to change the base?
Conversation
1b0239b
to
e723d34
Compare
This pull request has been marked as ready for review. |
Thanks for fixing the issue I encountered. In the description are some specific cases mentioned which are not covered by this fix. What would be required to fix those cases? I could help. |
It seems to me that Currently, there is Would it make sense to have a
This would also be an option for many more functions, such as |
thats exactly what this PR is doing.
I think thats not possible, because a
for this |
Thanks for your answer, I appreciate the insights! Could you clarify the following for me?
Is that not enough to ask the scope for the return type ( |
its enough to calculate the return-type of the thats also the reason why my current approch doesn't work for |
ce9e0fc
to
6a187b6
Compare
@leongersen thanks to some great playground changes by ondrej, the opt-in only rule errors now show up: |
I've reported another issue on this topic. This one isn't due to array-key related functions, so I'm wondering if this fits within the solution-direction chosen here. |
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 it work for
$array[count($array) - 1]
and other calls, by adding those conditions in NonexistentOffsetInArrayDimFetchCheck
?
src/Analyser/TypeSpecifier.php
Outdated
if ( | ||
$expr->expr instanceof FuncCall | ||
&& $expr->expr->name instanceof Name | ||
&& in_array($expr->expr->name->toLowerString(), ['array_search'], true) |
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.
You may prefer to use ===
rather than in_array check (maybe better perf ?)
Yes, see #3766 (comment) |
&& in_array($expr->expr->left->name->toLowerString(), ['count', 'sizeof'], true) | ||
&& count($expr->expr->left->getArgs()) >= 1 | ||
&& $expr->expr->right instanceof Node\Scalar\Int_ | ||
&& $expr->expr->right->value === 1 |
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.
"count - 1" is definitely the most common usecase.
However "count - N" is quite common too - can this usecase be supported as well when the "count" is higher than "N"?
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.
Count -N only works if the length of the array is known at static analysis time. Not sure how common/useful/likely this is in practice
Count -1 works pretty good because we know about non-emptiness in a lot more cases
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 mean https://phpstan.org/r/779c2b7e-977c-4df6-ae27-970c1a147529 - in this case, the minimal count is known.
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.
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.
Yes, that should be covered there indeed
fixes some false positives we see with
reportPossiblyNonexistentGeneralArrayOffset
.basic idea is to infer a expression type for
$array[$last]
after$last = array_key_last($array);
based on the iterable-type of a non-empty$array
.refs phpstan/phpstan#11020
this PR fixes code like
but not like (in which no intermediate variable is used)