vimeo / psalm

A static analysis tool for finding errors in PHP applications
https://psalm.dev
MIT License
5.54k stars 660 forks source link

True comparison on null-safe method call of nullable object asserts object as non-nullable in elseif #9804

Open tscni opened 1 year ago

tscni commented 1 year ago

Without null-safe operator on first check: https://psalm.dev/r/b2ef61192d With null-safe operator on first check: https://psalm.dev/r/ff20aa26bc (this is the issue)

I suppose the one without the null-safe operator failing is intended because $something->isA() means that $something cannot be nullable beyond it, as it'd have errored otherwise. Maybe this hints at the solution?

The issue disappears when the result of the method is compared against a non-true value: https://psalm.dev/r/2c16762b74

psalm-github-bot[bot] commented 1 year ago

I found these snippets:

https://psalm.dev/r/b2ef61192d ```php isA()) { echo 'a'; } elseif ($something?->isB()) { echo 'b'; } ``` ``` Psalm output (using commit cb34901): ERROR: PossiblyNullReference - 16:17 - Cannot call method isA on possibly null value ERROR: TypeDoesNotContainNull - 18:11 - Something does not contain null ERROR: RedundantCondition - 18:11 - Type Something for $something is never null ```
https://psalm.dev/r/ff20aa26bc ```php isA()) { echo 'a'; } elseif ($something?->isB()) { echo 'b'; } ``` ``` Psalm output (using commit cb34901): ERROR: RedundantCondition - 18:11 - $something is null has already been asserted ERROR: NullReference - 18:24 - Cannot call method isB on null value ERROR: TypeDoesNotContainType - 18:11 - Type null for $something is always !null ```
https://psalm.dev/r/2c16762b74 ```php isA() == 1) { echo 'a'; } elseif ($something?->isB()) { echo 'b'; } ``` ``` Psalm output (using commit cb34901): No issues! ```
kylekatarnls commented 10 months ago

Likely the same root cause, with this cause: https://psalm.dev/r/fa5d15a8ee

PossiblyNullReference false positive is triggered (impossible because $a cannot be truthy if $b === null

psalm-github-bot[bot] commented 10 months ago

I found these snippets:

https://psalm.dev/r/fa5d15a8ee ```php getFoo(); $c = 'none'; if ($a) { $c = $b->getBar(); } echo $c; ``` ``` Psalm output (using commit 147505c): ERROR: PossiblyNullReference - 14:14 - Cannot call method getBar on possibly null value ```