Skip to content
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

false is not eliminated when comparing against != "" #10547

Open
bwoebi opened this issue Jan 14, 2024 · 7 comments
Open

false is not eliminated when comparing against != "" #10547

bwoebi opened this issue Jan 14, 2024 · 7 comments

Comments

@bwoebi
Copy link

bwoebi commented Jan 14, 2024

A comparison if ($key != "") { ... } does still identify $key as being string|false instead of string within the if.

https://psalm.dev/r/4fb572a4fe

The goal is being able to simply compare is not empty and not false at once.

Related to #6965.

Copy link

I found these snippets:

https://psalm.dev/r/4fb572a4fe
<?php

class A {
    private ?string $prop = null;
    
    public function __construct() {
        if ("" != $env = getenv("TEST")) {
        	$this->prop = $env;
        }
    }
}
Psalm output (using commit a75d26a):

ERROR: PossiblyFalsePropertyAssignmentValue - 8:24 - $this->prop with non-falsable declared type 'null|string' cannot be assigned possibly false type 'false|string'

@bwoebi bwoebi changed the title Psalm does not eliminate false when comparing against != "" false is not eliminated when comparing against != "" Jan 14, 2024
@danog
Copy link
Collaborator

danog commented Jan 18, 2024

Just using a direct check fixes: https://psalm.dev/r/fb503c39ce

Now, a new issue is emitted due to the recently merged #10502, and both in case of the != '' comparison and in this new issue, the answer I'm inclined to give is the same: loose comparisons are generally a bad idea, and should be avoided whenever possible.

Copy link

I found these snippets:

https://psalm.dev/r/fb503c39ce
<?php

class A {
    private ?string $prop = null;
    
    public function __construct() {
        if ($env = getenv("TEST")) {
        	$this->prop = $env;
        }
    }
}
Psalm output (using commit a2140cc):

ERROR: RiskyTruthyFalsyComparison - 7:13 - Operand of type false|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead.

@bwoebi
Copy link
Author

bwoebi commented Jan 18, 2024

A direct check would also compare against "0" which would not be intended here. I want just "" and null/false basically.

Obviously, writing it out would work, but it's extra verbose and also less efficient code.

@kkmuffme
Copy link
Contributor

kkmuffme commented Feb 1, 2024

You could just use !empty()

If you really need this, give a PR a try
(since I doubt anybody of the existing contributors will fix this, since most people use/require strict comparisons bc the loose comparisons are a pain and huge source of bugs)

@bwoebi
Copy link
Author

bwoebi commented Feb 6, 2024

empty() sadly also compares against "0" :-/

@danog
Copy link
Collaborator

danog commented Feb 6, 2024

loose comparisons are a pain and huge source of bugs

+++, it along with empty and isset are banned in my codebase (and I'm very thankful for that)

I consider this issue as super low priority, I'd rather finish working on #10577 first :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants