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

report error for non-strict or empty comparison on truthy+falsy union #10502

Merged

Conversation

kkmuffme
Copy link
Contributor

@kkmuffme kkmuffme commented Dec 18, 2023

@kkmuffme kkmuffme marked this pull request as ready for review December 18, 2023 13:59
@kkmuffme
Copy link
Contributor Author

kkmuffme commented Dec 18, 2023

@orklah looks like this PR strikes a chord, as this issue is extremely widespread.

There's no way I can fix all these existing errors - can we update the baseline file please?

The shepherd ones should be fixed by someone eventually, as I'm sure there are at least a couple more bugs in psalm, similar to what I fixed in #10500 - just fixing those shepherd will fix them. But this needs to be on a separate issue/PR (those are all good first issues), as otherwise this PR will be ready come Psalm version 17...

@orklah
Copy link
Collaborator

orklah commented Jan 9, 2024

I have no issue with baselining real bugs in Psalm itself.

Though it seems tests are failing a lot too and this is more an issue...

@kkmuffme
Copy link
Contributor Author

Though it seems tests are failing a lot too and this is more an issue...

Which tests specifically? I only see tests that fail because they have that issue and it's reporting them as it should. Or what do you mean? (or is there no baseline for the tests themselves?)

@orklah
Copy link
Collaborator

orklah commented Jan 11, 2024

there is no baseline for tests, the only baseline we have is for Psalm analyzing its own code

@kkmuffme kkmuffme force-pushed the warn-for-non-strict-comparisons-on-truthy-falsy-types branch 2 times, most recently from 38e80ce to 02c4ead Compare January 12, 2024 19:57
@kkmuffme kkmuffme changed the title report error for non-strict comparison on truthy+falsy union report error for non-strict or empty comparison on truthy+falsy union Jan 12, 2024
@kkmuffme kkmuffme force-pushed the warn-for-non-strict-comparisons-on-truthy-falsy-types branch 4 times, most recently from 8d79b3c to e925151 Compare January 13, 2024 15:20
@kkmuffme
Copy link
Contributor Author

kkmuffme commented Jan 13, 2024

Ok, this was a pain :( I fixed them all now

3 points I realized when fixing the issues:

  • TypeDoesNotContainType might be confusing for this issue, so I created a new error type (RiskyTruthyFalsyComparison)
  • the same issue also exists in empty() => added this check there too*
  • lots of tests that reported that issue had exactly this issue, where it was unclear whether it meant to compare for the falsy/truthy type or also for the falsy/truthy possible type in the otherwise truthy type. I just made assumptions where it was possible and ignored the issue in all other ones to not risk breaking the test/intention of the test
  • fixed some spelling mistakes and bugs in unrelated tests
  • fixed empty() return type to be more specific
  • fixed keyed arrays possibly undefined types to actually include null when not verified (generic arrays still have the previous behavior)

*because of this, people should ideally use your plugin https://github.com/orklah/psalm-not-empty, as that will get rid of lots of errors. Maybe we should include this in psalm core by default?

Please update the baseline and merge this :-) @orklah

@orklah
Copy link
Collaborator

orklah commented Jan 14, 2024

You can update the baseline on your side by just running psalm with --update-baseline. Other than that and my comment above, seems good to merge :)

@kkmuffme kkmuffme force-pushed the warn-for-non-strict-comparisons-on-truthy-falsy-types branch from cf94b2d to f34ec2c Compare January 15, 2024 09:11
@kkmuffme
Copy link
Contributor Author

kkmuffme commented Jan 15, 2024

Thanks, baseline updating worked using composer psalm-set-baseline

Also test-with-real-projects still fails - I guess there's a baseline too? How do I update that one?

@danog danog added the release:feature The PR will be included in 'Features' section of the release notes label Jan 15, 2024
@kkmuffme
Copy link
Contributor Author

Yes. Afaik there were some tests that used the elvis which I changed to a normal ternary, bc I wasn't aware of this.
I'm not available for the next 2 weeks, anybody feel free to PR this.

@veewee
Copy link
Contributor

veewee commented Jan 18, 2024

Psalm is smart enough to narrow down types in situations like these, so I'm using it as a shortcut to do so in a lot of places. It's giving me quite some errors which I wouldn't consider harmfull but rather expected behaviour.
I'm not sure if dealing with elvis is enough, cause it's also valid when doing ternary checks or even in if-based validations.

But mostly I'm not sure if doing strict comparison over taking the educated shortcut is adding a lot of value.
So for now I'm gonna opt-out on this feature cause it feels a bit too restrictive.

I might be missing the context in which scenarios this is actually risky though.

@theodorejb
Copy link
Contributor

theodorejb commented Jan 18, 2024

I'm surprised to see a change like this introduced in a minor release. It is a very common pattern to use checks like:

if (!$possiblyEmptyStringOrNull) {
    throw new Exception("Missing required value");
}

// or
if ($intFlagOrNull) {
    doThingSinceOptionIsEnabled();
}

// or
$date = $row['dateStrOrNull'] ? new DateTime($row['dateStrOrNull']) : null;

I also don't see these as risky - it's using the language as designed to easily handle null values the same way as an empty string or 0 integer.

@kkmuffme
Copy link
Contributor Author

I'm surprised to see a change like this introduced in a minor release

@theodorejb could you clarify why? As that would allow us to improve the readme perhaps.
Anyway, you can just suppress it in your config. When we released PHP 8.2 or 8.3 we included changes that had way more "breaking" character than what you have here.


The reason why I added this rule is bc this risky - while you might be aware when you create the code, refactoring might introduce unwanted behavior - but even when you write code you might not be aware. If you're in an organization with loads of developers, and I'm happy that psalm will catch those rather unlikely things too, since it's something that happens/get forgotten when you also have less experienced people write code.

The impetus is a bug in psalm itself that was caused by one of these unstrict comparisons: #10500

@kkmuffme
Copy link
Contributor Author

Btw. the feedback is exactly what I expected from this rule, since it reports tons of errors for lots of cases where it might not be an issue at all in the end - but that's what happens with ambiguous code.
Especially since stricter types and PHP 8, you rarely ever see someone do $foo == false as most codebases disallow that. But for whatever reason they're fine with !$foo which is just the same thing.

@kkmuffme
Copy link
Contributor Author

@veewee

Does it make sense to be very strict about Risky checks by default or are there acceptable scenarios ?

Yes there are, it's just impossible to know them from static analysis, since we cannot analyze the intent easily.
Just like there are scenarios where you can $foo == false, most codebases require you to use a strict comparison

@theodorejb
Copy link
Contributor

theodorejb commented Jan 18, 2024

could you clarify why?

Because these code patterns are very common and typically used intentionally to simplify code.

Now instead of if (!$possiblyEmptyStringOrNull) I have to write if ($possiblyEmptyStringOrNull === null || $possiblyEmptyStringOrNull === '' || $possiblyEmptyStringOrNull === '0') for the equivalent check. It makes the code far more verbose.

Having to write out all the extra conditions is itself risky since it introduces the possibility for bugs (e.g. accidentally using && instead of || or !== instead of ===).

@kkmuffme
Copy link
Contributor Author

Yeah, that's the purpose. You can just suppress it via the config.

Does your codebase allow if ($possiblyEmptyStringOrNull == false) ? If not, then it shouldn't allow if (!$possiblyEmptyStringOrNull) either

@danog
Copy link
Collaborator

danog commented Jan 18, 2024

All in all, this new check is quite strict and is bound to affect a lot of codebases, but IMO, it's something that can catch potential bugs, which is always a good thing, and the reason why I merged this.

I did have some doubts on whether it should be on level 1 instead of level 2, maybe it's better to lower its level...

@theodorejb
Copy link
Contributor

theodorejb commented Jan 18, 2024

The impetus is a bug in psalm itself that was caused by one of these unstrict comparisons: #10500

It looks like in this case the bug was with !$arrayOrNull checks, which incorrectly handled an empty array the same as null.

Perhaps the new error could be limited to array comparisons like this? That does seem far more risky than checking for falsy strings/integers.

@kkmuffme
Copy link
Contributor Author

Totally an option to split it into separate errors - the one we have now as fallback (e.g. where you have multiple) and for more specific cases, e.g. arrays (RiskyTruthyFalsyArrayComparison) or strings (RiskyTruthyFalsyStringComparison) you create a separate errors.
This is simple to add to psalm and you could give it a PR a try? @theodorejb

@bwoebi
Copy link

bwoebi commented Jan 19, 2024

I would love to see separate checks for if (something-which-can-be-string) and if(something-never-string).
From my experience I've never had issues with array|null or bool|null or such, but only with strings, where "0" was also included, and if ("" != $str) instead if ($str) would be the right choice. For explicit checking for "0", "" and false/null there's then if ($str == true).

oguzhand95 referenced this pull request in cerbos/cerbos-sdk-php Jan 26, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [phpstan/phpstan](https://togithub.com/phpstan/phpstan) | `1.10.55` ->
`1.10.57` |
[![age](https://developer.mend.io/api/mc/badges/age/packagist/phpstan%2fphpstan/1.10.57?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/packagist/phpstan%2fphpstan/1.10.57?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/packagist/phpstan%2fphpstan/1.10.55/1.10.57?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/packagist/phpstan%2fphpstan/1.10.55/1.10.57?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [phpunit/phpunit](https://phpunit.de/)
([source](https://togithub.com/sebastianbergmann/phpunit)) | `10.5.7` ->
`10.5.9` |
[![age](https://developer.mend.io/api/mc/badges/age/packagist/phpunit%2fphpunit/10.5.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/packagist/phpunit%2fphpunit/10.5.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/packagist/phpunit%2fphpunit/10.5.7/10.5.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/packagist/phpunit%2fphpunit/10.5.7/10.5.9?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
| [vimeo/psalm](https://togithub.com/vimeo/psalm) | `5.19.0` -> `5.20.0`
|
[![age](https://developer.mend.io/api/mc/badges/age/packagist/vimeo%2fpsalm/5.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/packagist/vimeo%2fpsalm/5.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/packagist/vimeo%2fpsalm/5.19.0/5.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/packagist/vimeo%2fpsalm/5.19.0/5.20.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>phpstan/phpstan (phpstan/phpstan)</summary>

###
[`v1.10.57`](https://togithub.com/phpstan/phpstan/compare/1.10.56...1.10.57)

[Compare
Source](https://togithub.com/phpstan/phpstan/compare/1.10.56...1.10.57)

###
[`v1.10.56`](https://togithub.com/phpstan/phpstan/releases/tag/1.10.56)

[Compare
Source](https://togithub.com/phpstan/phpstan/compare/1.10.55...1.10.56)

# Major new feature 🚀

- New PHPDoc tags: `@phpstan-require-extends`,
`@phpstan-require-implements`,
[#&#8203;10302](https://togithub.com/phpstan/phpstan/issues/10302),
[#&#8203;9899](https://togithub.com/phpstan/phpstan/issues/9899),
[#&#8203;8550](https://togithub.com/phpstan/phpstan/issues/8550), thanks
[@&#8203;staabm](https://togithub.com/staabm)!
- Learn more: [Making `@property` PHPDoc above interfaces work on PHP
8.2+](https://phpstan.org/blog/solving-phpstan-access-to-undefined-property#making-%40property-phpdoc-above-interfaces-work-on-php-8.2%2B)
- [Enforcing class inheritance for interfaces and
traits](https://phpstan.org/writing-php-code/phpdocs-basics#enforcing-class-inheritance-for-interfaces-and-traits)
- [Enforcing implementing an interface for
traits](https://phpstan.org/writing-php-code/phpdocs-basics#enforcing-implementing-an-interface-for-traits)
- Development of this feature was kindly sponsored by [Pixel &
Tonic](https://pixelandtonic.com/), the team behind [Craft
CMS](https://craftcms.com/)

# Improvements 🔧

- Scope - function call stack includes parameters too
(phpstan/phpstan-src@b87e5c4),
[https://github.com/phpstan/phpstan-deprecation-rules/issues/107](https://togithub.com/phpstan/phpstan-deprecation-rules/issues/107)

# Bugfixes 🐛

- Process `match` arm condition before analysing the body
(phpstan/phpstan-src@2b74aa8),
[#&#8203;10418](https://togithub.com/phpstan/phpstan/issues/10418)

# Function signature fixes 🤖

- Fix transliterator function maps
([#&#8203;2862](https://togithub.com/phpstan/phpstan-src/pull/2862)),
thanks [@&#8203;PrinsFrank](https://togithub.com/PrinsFrank)!
- Fix duplicate array key `Yaf_Response_Http::__clone`
([#&#8203;2863](https://togithub.com/phpstan/phpstan-src/pull/2863)),
thanks [@&#8203;PrinsFrank](https://togithub.com/PrinsFrank)!
- Add array shape for `transliterator::listIDs` return type
([#&#8203;2865](https://togithub.com/phpstan/phpstan-src/pull/2865)),
thanks [@&#8203;PrinsFrank](https://togithub.com/PrinsFrank)!
- `strtok()` always returns a `non-empty-string` when it does not return
false
([#&#8203;2869](https://togithub.com/phpstan/phpstan-src/pull/2869)),
thanks [@&#8203;staabm](https://togithub.com/staabm)!

# Internals 🔍

- Prevent repetative calls to `Type::getConstantArrays()`
([#&#8203;2864](https://togithub.com/phpstan/phpstan-src/pull/2864)),
thanks [@&#8203;staabm](https://togithub.com/staabm)!
- Remove redundant condition in ParametersAcceptorSelector
([#&#8203;2867](https://togithub.com/phpstan/phpstan-src/pull/2867)),
thanks [@&#8203;mad-briller](https://togithub.com/mad-briller)!
- Simplify default return path in extensions
([#&#8203;2868](https://togithub.com/phpstan/phpstan-src/pull/2868)),
thanks [@&#8203;staabm](https://togithub.com/staabm)!
- Reduce unnecessary calls to `Scope::getFunctionType()`
([#&#8203;2872](https://togithub.com/phpstan/phpstan-src/pull/2872)),
thanks [@&#8203;staabm](https://togithub.com/staabm)!

</details>

<details>
<summary>sebastianbergmann/phpunit (phpunit/phpunit)</summary>

###
[`v10.5.9`](https://togithub.com/sebastianbergmann/phpunit/compare/10.5.8...10.5.9)

[Compare
Source](https://togithub.com/sebastianbergmann/phpunit/compare/10.5.8...10.5.9)

###
[`v10.5.8`](https://togithub.com/sebastianbergmann/phpunit/compare/10.5.7...10.5.8)

[Compare
Source](https://togithub.com/sebastianbergmann/phpunit/compare/10.5.7...10.5.8)

</details>

<details>
<summary>vimeo/psalm (vimeo/psalm)</summary>

### [`v5.20.0`](https://togithub.com/vimeo/psalm/releases/tag/5.20.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.19.1...5.20.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Features

- report error for non-strict or empty comparison on truthy+falsy union
by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10502](https://togithub.com/vimeo/psalm/pull/10502)

##### Fixes

- Fix template, conditional array keys by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10568](https://togithub.com/vimeo/psalm/pull/10568)

**Full Changelog**:
vimeo/psalm@5.19.1...5.20.0

### [`v5.19.1`](https://togithub.com/vimeo/psalm/releases/tag/5.19.1)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.19.0...5.19.1)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Fixes

- Deprecated Template Classes are not ignored by
[@&#8203;psalm-suppress](https://togithub.com/psalm-suppress)
DeprecatedClass by
[@&#8203;samlitowitz](https://togithub.com/samlitowitz) in
[https://github.com/vimeo/psalm/pull/10518](https://togithub.com/vimeo/psalm/pull/10518)
- Implement \__set method in SimpleXMLElement stub by
[@&#8203;kthaler](https://togithub.com/kthaler) in
[https://github.com/vimeo/psalm/pull/10536](https://togithub.com/vimeo/psalm/pull/10536)
- Make getrandmax type more specific and unserialize to require
class-string by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10540](https://togithub.com/vimeo/psalm/pull/10540)
- Fix mb_get_info can return null - CI failing bc of reflection by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10543](https://togithub.com/vimeo/psalm/pull/10543)
- make basename & dirname return types more specific by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10545](https://togithub.com/vimeo/psalm/pull/10545)
- add support for extract to set variables for keyed arrays and respect
EXTR_SKIP by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10544](https://togithub.com/vimeo/psalm/pull/10544)
- remove redundat directory separator which caused "//" in path not
found errors by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10542](https://togithub.com/vimeo/psalm/pull/10542)
- Fix empty literal string becomes non-empty-string by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10499](https://togithub.com/vimeo/psalm/pull/10499)

#### New Contributors

- [@&#8203;samlitowitz](https://togithub.com/samlitowitz) made their
first contribution in
[https://github.com/vimeo/psalm/pull/10518](https://togithub.com/vimeo/psalm/pull/10518)
- [@&#8203;kthaler](https://togithub.com/kthaler) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10536](https://togithub.com/vimeo/psalm/pull/10536)

**Full Changelog**:
vimeo/psalm@5.19.0...5.20.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://togithub.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/cerbos/cerbos-sdk-php).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMzUuMCIsInVwZGF0ZWRJblZlciI6IjM3LjEzNS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: Oğuzhan Durgun <[email protected]>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@aguerre
Copy link

aguerre commented Feb 8, 2024

I'm confused with this new report on empty() function, as it is usually used to check if it's null or "empty scalar value" (like 0 or ''). There is no risky comparison in it.
It's too sad that i had to deactivate this rule because of empty() checks warnings even though it is useful for other cases.
Can you imagine to split this rule in two ?

@kkmuffme
Copy link
Contributor Author

kkmuffme commented Feb 8, 2024

Could you please create a small code snippet on psalm.dev to give an example of your use case, where you think it's not risky, as that might help identify cases where this rule shouldn't report an error.

@kkmuffme kkmuffme deleted the warn-for-non-strict-comparisons-on-truthy-falsy-types branch February 8, 2024 15:26
@aguerre
Copy link

aguerre commented Feb 8, 2024

Yes, check this : https://psalm.dev/r/f95fd49c39

Copy link

I found these snippets:

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

/**
 * Typical Doctrine Entity used in form
 */
class Address
{
    private ?string $streetName = null;
    private ?string $city = null;
    private ?int $zipCode = null;
    private ?string $country = null;

    public function isEmpty(): bool
    {
        return empty($this->streetName)
            && empty($this->city)
            && empty($this->zipCode)
            && empty($this->country)
        ;
    }
}
Psalm output (using commit 4b2c698):

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

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

ERROR: RiskyTruthyFalsyComparison - 17:16 - Operand of type int|null contains type int, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead.

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

@kkmuffme
Copy link
Contributor Author

kkmuffme commented Feb 8, 2024

This is an example of where this rule makes sense: not all countries use zipCodes or people input an invalid value (0). How would you differentiate between a '' value and a not-set (null) value if you just check with empty?

@aguerre
Copy link

aguerre commented Feb 12, 2024

This is a french example where all fields are required, sorry for the lack of precision.
Here we WANT to check if null or empty string. The user shall not pass if there is no address set (untouched field or empty string post). I don't want to differentiate at this point.

@kkmuffme
Copy link
Contributor Author

If it doesn't matter for you in the first place, then why use null at all? Could just initialized it with '' instead of null.
Then use === '' instead of empty

@stronk7
Copy link

stronk7 commented Feb 15, 2024

I'm afraid, but this is the first time that I'm going to need to disable something because the solution doesn't make any sense to me.

Sure that it has been introduced for a good reason, but it destroys any attempt to use elvis, empty() and simple conditions when you're sure that the behaviour is the same for null/false/empty string (aka any falsy).

I honestly cannot see any advantage having to switch to the long alternative in a lot of cases. Said with all respects!

https://psalm.dev/r/78ca579efd

Ciao :-)

PS: In fact, this very same PR, where the feature was implemented is a great representation of the impact that it's going to cause on any project. The changeset is massive. Again, just IMO.

Copy link

I found these snippets:

https://psalm.dev/r/78ca579efd
<?php

// Just a silly example with getenv() but can be other thousands of things.
$reallyRiskyOhMy = getenv('SOME') ?: 'default';
$soIsThisTooOhMy = empty(getenv('SOME')) ?: 'default';
if (getenv('SOME')) {
    $notSureHereOhMy = getenv('SOME');
} else {
    $notSureHereOhMy = 'default';
}

// Why do I need this when I want the same behaviour for any empty/falsy.
$doINeedThisOhMy = (getenv('SOME') !== false && getenv('SOME') !== '') ? getenv('SOME') : 'default';

echo $reallyRiskyOhMy;
echo $soIsThisTooOhMy;
echo $notSureHereOhMy;
echo $doINeedThisOhMy;
Psalm output (using commit 639bed0):

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

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

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

tcarrio referenced this pull request in open-feature/php-sdk May 7, 2024
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [vimeo/psalm](https://togithub.com/vimeo/psalm) | `~5.17.0` ->
`~5.24.0` |
[![age](https://developer.mend.io/api/mc/badges/age/packagist/vimeo%2fpsalm/5.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/packagist/vimeo%2fpsalm/5.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/packagist/vimeo%2fpsalm/5.17.0/5.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/packagist/vimeo%2fpsalm/5.17.0/5.24.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>vimeo/psalm (vimeo/psalm)</summary>

### [`v5.24.0`](https://togithub.com/vimeo/psalm/releases/tag/5.24.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.23.1...5.24.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Features

- Allow specifying flags to Codebase::isTypeContainedByType by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10829](https://togithub.com/vimeo/psalm/pull/10829)
- Allow more callable types as subtypes of `callable` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10805](https://togithub.com/vimeo/psalm/pull/10805)
- Report `parent` being used in callable context when the class does not
extend anything by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10838](https://togithub.com/vimeo/psalm/pull/10838)
- Report error for additional deprecated arg types in PHP 8.1/8.3 by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10824](https://togithub.com/vimeo/psalm/pull/10824)
- Add MissingClassConstType Issue by
[@&#8203;jack-worman](https://togithub.com/jack-worman) in
[https://github.com/vimeo/psalm/pull/10828](https://togithub.com/vimeo/psalm/pull/10828)
- Enforce parameter names for consistent constructors by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10821](https://togithub.com/vimeo/psalm/pull/10821)
- Add misc missing errors for invalid callable methods by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10839](https://togithub.com/vimeo/psalm/pull/10839)

##### Fixes

- Forbid named arguments for ArrayAcccess methods by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10804](https://togithub.com/vimeo/psalm/pull/10804)
- Don't crash on invalid templates by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10806](https://togithub.com/vimeo/psalm/pull/10806)
- report error for single param name mismatch too since named args can
even be used then by [@&#8203;kkmuffme](https://togithub.com/kkmuffme)
in
[https://github.com/vimeo/psalm/pull/10822](https://togithub.com/vimeo/psalm/pull/10822)
- add support for named arguments for filter_var and filter_input by
[@&#8203;pilif](https://togithub.com/pilif) in
[https://github.com/vimeo/psalm/pull/10815](https://togithub.com/vimeo/psalm/pull/10815)
- When inside isset, make array fetch result nullable by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10756](https://togithub.com/vimeo/psalm/pull/10756)
- Promoted properties missing in extended \__construct should report
PropertyNotSetInConstructor by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10817](https://togithub.com/vimeo/psalm/pull/10817)
- Updating signature of `getmxrr()` by
[@&#8203;ThomasLandauer](https://togithub.com/ThomasLandauer) in
[https://github.com/vimeo/psalm/pull/10847](https://togithub.com/vimeo/psalm/pull/10847)
- Improve string-int juggle consistency in array keys and display for
int-like strings in type by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10814](https://togithub.com/vimeo/psalm/pull/10814)
- Fix storage not available in thread for intersection doc types by
[@&#8203;simonberger](https://togithub.com/simonberger) in
[https://github.com/vimeo/psalm/pull/10856](https://togithub.com/vimeo/psalm/pull/10856)
- Don't emit MissingOverrideAttribute for implicit Stringable
implementations by [@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10858](https://togithub.com/vimeo/psalm/pull/10858)
- Specify array return type of session_get_cookie_params by
[@&#8203;jorgsowa](https://togithub.com/jorgsowa) in
[https://github.com/vimeo/psalm/pull/10859](https://togithub.com/vimeo/psalm/pull/10859)
- Unknown [@&#8203;psalm](https://togithub.com/psalm) annotation should
not make whole docblock invalid by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10885](https://togithub.com/vimeo/psalm/pull/10885)
- Add `mail` to impure functions list by
[@&#8203;smaddock](https://togithub.com/smaddock) in
[https://github.com/vimeo/psalm/pull/10923](https://togithub.com/vimeo/psalm/pull/10923)
- Update PHP 8.2 Call map delta with refined types for string comparison
functions by [@&#8203;gsteel](https://togithub.com/gsteel) in
[https://github.com/vimeo/psalm/pull/10883](https://togithub.com/vimeo/psalm/pull/10883)

##### Docs

- document that
[@&#8203;psalm-internal](https://togithub.com/psalm-internal) works for
namespace + class too by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10866](https://togithub.com/vimeo/psalm/pull/10866)

##### Internal changes

- fix tests running with other than called PHP binary if called with a
non-default PHP binary by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10842](https://togithub.com/vimeo/psalm/pull/10842)
- Explicitly set value in config to fix warning in tests by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10843](https://togithub.com/vimeo/psalm/pull/10843)
- \[PHP 8.4] Fixes for implicit nullability deprecation by
[@&#8203;Ayesh](https://togithub.com/Ayesh) in
[https://github.com/vimeo/psalm/pull/10832](https://togithub.com/vimeo/psalm/pull/10832)
- Throw exception instead of silently logging issues occurred during
scan by [@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10902](https://togithub.com/vimeo/psalm/pull/10902)

##### Other changes

- Fix conditional on non empty literal string by
[@&#8203;VincentLanglet](https://togithub.com/VincentLanglet) in
[https://github.com/vimeo/psalm/pull/10912](https://togithub.com/vimeo/psalm/pull/10912)
- Ignore jsonSerialize for implementors of JsonSerializable by
[@&#8203;josephwynn-sc](https://togithub.com/josephwynn-sc) in
[https://github.com/vimeo/psalm/pull/10891](https://togithub.com/vimeo/psalm/pull/10891)
- Add XML functions to ImpureFunctionsList
[#&#8203;10882](https://togithub.com/vimeo/psalm/issues/10882) by
[@&#8203;DKhalil](https://togithub.com/DKhalil) in
[https://github.com/vimeo/psalm/pull/10887](https://togithub.com/vimeo/psalm/pull/10887)

#### New Contributors

- [@&#8203;Ayesh](https://togithub.com/Ayesh) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10832](https://togithub.com/vimeo/psalm/pull/10832)
- [@&#8203;smaddock](https://togithub.com/smaddock) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10923](https://togithub.com/vimeo/psalm/pull/10923)
- [@&#8203;josephwynn-sc](https://togithub.com/josephwynn-sc) made their
first contribution in
[https://github.com/vimeo/psalm/pull/10891](https://togithub.com/vimeo/psalm/pull/10891)
- [@&#8203;DKhalil](https://togithub.com/DKhalil) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10887](https://togithub.com/vimeo/psalm/pull/10887)

**Full Changelog**:
vimeo/psalm@5.23.1...5.24.0

### [`v5.23.1`](https://togithub.com/vimeo/psalm/releases/tag/5.23.1)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.23.0...5.23.1)

<!-- Release notes generated using configuration in .github/release.yml
at 5.23.x -->

#### What's Changed

##### Fixes

- Fixed analysis of existing static methods if the `__callStatic()`
method exists by [@&#8203;issidorov](https://togithub.com/issidorov) in
[https://github.com/vimeo/psalm/pull/10812](https://togithub.com/vimeo/psalm/pull/10812)

**Full Changelog**:
vimeo/psalm@5.23.0...5.23.1

### [`v5.23.0`](https://togithub.com/vimeo/psalm/releases/tag/5.23.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.22.2...5.23.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Features

- Update PHP 8.2 stubs to include `SensitiveParameterValue` by
[@&#8203;gsteel](https://togithub.com/gsteel) in
[https://github.com/vimeo/psalm/pull/10726](https://togithub.com/vimeo/psalm/pull/10726)
- Add list of statements to BeforeFileAnalysisEvent by
[@&#8203;ohader](https://togithub.com/ohader) in
[https://github.com/vimeo/psalm/pull/10728](https://togithub.com/vimeo/psalm/pull/10728)
- Forbid iterating over generators with non-nullable `send()` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10697](https://togithub.com/vimeo/psalm/pull/10697)
- Initial support for named parameters for callables by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10772](https://togithub.com/vimeo/psalm/pull/10772)

##### Fixes

- Improve randomizer stubs by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10709](https://togithub.com/vimeo/psalm/pull/10709)
- Fix detecting magic static methods by
[@&#8203;issidorov](https://togithub.com/issidorov) in
[https://github.com/vimeo/psalm/pull/10704](https://togithub.com/vimeo/psalm/pull/10704)
- Fix non-empty-lowercase-string handling with literal non-lowercase
strings by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10722](https://togithub.com/vimeo/psalm/pull/10722)
- Fix RiskyTruthyFalsyComparison irrelevant errors when there is no
explicit truthy/falsy type by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10733](https://togithub.com/vimeo/psalm/pull/10733)
- Allow `Override` attribute to be used in pure contexts by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10734](https://togithub.com/vimeo/psalm/pull/10734)
- Revert "Allow tainted numerics except for 'html' and 'has_quotes'" by
[@&#8203;ohader](https://togithub.com/ohader) in
[https://github.com/vimeo/psalm/pull/10729](https://togithub.com/vimeo/psalm/pull/10729)
- Fix loading stubs from phar file on Windows by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10748](https://togithub.com/vimeo/psalm/pull/10748)
- Fix a false flag issue with InvalidConstantAssignmentValue by
[@&#8203;MelechMizrachi](https://togithub.com/MelechMizrachi) in
[https://github.com/vimeo/psalm/pull/10738](https://togithub.com/vimeo/psalm/pull/10738)
- Set inside_isset false when analyzing ArrayDimFetch index by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10752](https://togithub.com/vimeo/psalm/pull/10752)
- Set inside_isset = false when analyzing arguments by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10753](https://togithub.com/vimeo/psalm/pull/10753)
- Fix PHP notice - crash on invalid taint-escape by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10760](https://togithub.com/vimeo/psalm/pull/10760)
- Fix version comparison for `@since` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10764](https://togithub.com/vimeo/psalm/pull/10764)
- Since annotations outside phpstub should not infer php version by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10769](https://togithub.com/vimeo/psalm/pull/10769)
- Backport `WeakMap` iterator fix from `master` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10778](https://togithub.com/vimeo/psalm/pull/10778)
- Namespace anonymous classes by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10779](https://togithub.com/vimeo/psalm/pull/10779)
- Update CallMap for sqlsrv_connect and sqlsrv_errors to match
reflection by [@&#8203;theodorejb](https://togithub.com/theodorejb) in
[https://github.com/vimeo/psalm/pull/10781](https://togithub.com/vimeo/psalm/pull/10781)
- `$resource` parameter of `mkdir()` is nullable since PHP 7.3 by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10802](https://togithub.com/vimeo/psalm/pull/10802)
- Use wider class-string when combining class strings with intersections
by [@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10800](https://togithub.com/vimeo/psalm/pull/10800)

##### Internal changes

- Use TaintKind/TaintKindGroup constants instead of string values by
[@&#8203;ohader](https://togithub.com/ohader) in
[https://github.com/vimeo/psalm/pull/10746](https://togithub.com/vimeo/psalm/pull/10746)
- Skip symlink test on Windows by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10749](https://togithub.com/vimeo/psalm/pull/10749)
- Avoid duplicating code for RiskyTruthyFalsyComparison by
[@&#8203;theodorejb](https://togithub.com/theodorejb) in
[https://github.com/vimeo/psalm/pull/10765](https://togithub.com/vimeo/psalm/pull/10765)
- fix PHP 8 tests running with wrong --php-version=/phpVersion= if not
explicitly specified by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10776](https://togithub.com/vimeo/psalm/pull/10776)
- CS fix by [@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10801](https://togithub.com/vimeo/psalm/pull/10801)

#### New Contributors

- [@&#8203;MelechMizrachi](https://togithub.com/MelechMizrachi) made
their first contribution in
[https://github.com/vimeo/psalm/pull/10738](https://togithub.com/vimeo/psalm/pull/10738)

**Full Changelog**:
vimeo/psalm@5.22.2...5.23.0

### [`v5.22.2`](https://togithub.com/vimeo/psalm/releases/tag/5.22.2)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.22.1...5.22.2)

<!-- Release notes generated using configuration in .github/release.yml
at 5.22.x -->

#### What's Changed

##### Fixes

- Catch missing classlike exceptions during scanning by
[@&#8203;weirdan](https://togithub.com/weirdan) and
[@&#8203;ohader](https://togithub.com/ohader) in
[https://github.com/vimeo/psalm/pull/10720](https://togithub.com/vimeo/psalm/pull/10720)

**Full Changelog**:
vimeo/psalm@5.22.1...5.22.2

### [`v5.22.1`](https://togithub.com/vimeo/psalm/releases/tag/5.22.1)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.22.0...5.22.1)

<!-- Release notes generated using configuration in .github/release.yml
at 5.22.x -->

#### What's Changed

##### Fixes

- Improve parsing of `@psalm-type` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10713](https://togithub.com/vimeo/psalm/pull/10713)

**Full Changelog**:
vimeo/psalm@5.22.0...5.22.1

### [`v5.22.0`](https://togithub.com/vimeo/psalm/releases/tag/5.22.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.21.1...5.22.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Features

- Allow inline comments in typedef shapes by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10623](https://togithub.com/vimeo/psalm/pull/10623)
- allow typedef imports from any kind of classlike by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10625](https://togithub.com/vimeo/psalm/pull/10625)
- Allow enum cases to be global constants by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10634](https://togithub.com/vimeo/psalm/pull/10634)
- New InvalidOverride issue for Override attribute by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10644](https://togithub.com/vimeo/psalm/pull/10644)
- Analyze dynamic names for static property and const fetches by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10629](https://togithub.com/vimeo/psalm/pull/10629)
- New MissingOverrideAttribute issue by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10651](https://togithub.com/vimeo/psalm/pull/10651)
- Flag `stdClass::__construct()` calls that have arguments by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10661](https://togithub.com/vimeo/psalm/pull/10661)
- Improve Reflection stubs by
[@&#8203;vudaltsov](https://togithub.com/vudaltsov) in
[https://github.com/vimeo/psalm/pull/10091](https://togithub.com/vimeo/psalm/pull/10091)
- Forbid constructors from returning any values by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10686](https://togithub.com/vimeo/psalm/pull/10686)
- Report first class callables generated for unknown static methods by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10691](https://togithub.com/vimeo/psalm/pull/10691)
- Process `@psalm-this-out` on `__construct()` as well by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10690](https://togithub.com/vimeo/psalm/pull/10690)
- Report invalid number of arguments for psalm-taint-\* by
[@&#8203;staabm](https://togithub.com/staabm) in
[https://github.com/vimeo/psalm/pull/10699](https://togithub.com/vimeo/psalm/pull/10699)

##### Fixes

- Fix ownerDocument type in dom-ext classes by
[@&#8203;fluffycondor](https://togithub.com/fluffycondor) in
[https://github.com/vimeo/psalm/pull/10619](https://togithub.com/vimeo/psalm/pull/10619)
- Fix numeric scalar validate filter var input return type wrong by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10621](https://togithub.com/vimeo/psalm/pull/10621)
- Stable baseline by [@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10633](https://togithub.com/vimeo/psalm/pull/10633)
- Allow sebastian/diff v6 by
[@&#8203;simPod](https://togithub.com/simPod) in
[https://github.com/vimeo/psalm/pull/10639](https://togithub.com/vimeo/psalm/pull/10639)
- CallMap: Adjust return type for `inotify_add_watch()` to `int|false`
by [@&#8203;UlrichEckhardt](https://togithub.com/UlrichEckhardt) in
[https://github.com/vimeo/psalm/pull/10637](https://togithub.com/vimeo/psalm/pull/10637)
- Fix check-type when using builtin types from within a namespace by
[@&#8203;robchett](https://togithub.com/robchett) in
[https://github.com/vimeo/psalm/pull/10648](https://togithub.com/vimeo/psalm/pull/10648)
- Do not add `callable` as a native property type by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10654](https://togithub.com/vimeo/psalm/pull/10654)
- Fix additional places where base_dir was broken due to missing
separator by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10630](https://togithub.com/vimeo/psalm/pull/10630)
- Late binding of enum cases by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10655](https://togithub.com/vimeo/psalm/pull/10655)
- Suppress `UndefinedClass` in `whatever_exists()` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10659](https://togithub.com/vimeo/psalm/pull/10659)
- Fix parsing magic method annotations by
[@&#8203;issidorov](https://togithub.com/issidorov) in
[https://github.com/vimeo/psalm/pull/10665](https://togithub.com/vimeo/psalm/pull/10665)
- Strip callmap prefixes from parameter names by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10666](https://togithub.com/vimeo/psalm/pull/10666)
- Narrow `ord()` return type to `int<0,255>` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10676](https://togithub.com/vimeo/psalm/pull/10676)
- Template union object incorrect assertions by
[@&#8203;robchett](https://togithub.com/robchett) in
[https://github.com/vimeo/psalm/pull/10677](https://togithub.com/vimeo/psalm/pull/10677)
- Don't show backtrace in `InvalidDocblock` issue message by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10679](https://togithub.com/vimeo/psalm/pull/10679)
- Class consts in array shapes by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10678](https://togithub.com/vimeo/psalm/pull/10678)
- Prevent mixed|null by
[@&#8203;robchett](https://togithub.com/robchett) in
[https://github.com/vimeo/psalm/pull/10675](https://togithub.com/vimeo/psalm/pull/10675)

##### Internal changes

- Drop unused local composer repo by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10647](https://togithub.com/vimeo/psalm/pull/10647)
- Clarify that Pull request labels failure is to be resolved by
maintainers by [@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10649](https://togithub.com/vimeo/psalm/pull/10649)
- Fix unstable `hasFullyQualified(Interface|Enum)()` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10603](https://togithub.com/vimeo/psalm/pull/10603)
- Revert partial mistakenly pushed fix by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10671](https://togithub.com/vimeo/psalm/pull/10671)

**Full Changelog**:
vimeo/psalm@5.21.1...5.22.0

### [`v5.21.1`](https://togithub.com/vimeo/psalm/releases/tag/5.21.1)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.21.0...5.21.1)

<!-- Release notes generated using configuration in .github/release.yml
at 5.21.x -->

#### What's Changed

##### Fixes

- Fix baseline loading for path specified on the command line by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10628](https://togithub.com/vimeo/psalm/pull/10628)

**Full Changelog**:
vimeo/psalm@5.21.0...5.21.1

### [`v5.21.0`](https://togithub.com/vimeo/psalm/releases/tag/5.21.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.20.0...5.21.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Features

- Allow importing typedefs from enums by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10617](https://togithub.com/vimeo/psalm/pull/10617)

##### Fixes

- Fix [#&#8203;10552](https://togithub.com/vimeo/psalm/issues/10552) by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10572](https://togithub.com/vimeo/psalm/pull/10572)
- Unit test improvements for php-parser 5 by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10574](https://togithub.com/vimeo/psalm/pull/10574)
- Fix template replacement edge case by
[@&#8203;klimick](https://togithub.com/klimick) in
[https://github.com/vimeo/psalm/pull/10586](https://togithub.com/vimeo/psalm/pull/10586)
- Switch condition order by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10594](https://togithub.com/vimeo/psalm/pull/10594)
- Partial revert "Fix auto completion by partial property or method" by
[@&#8203;issidorov](https://togithub.com/issidorov) in
[https://github.com/vimeo/psalm/pull/10588](https://togithub.com/vimeo/psalm/pull/10588)
- \[LSP] Add issue type in description by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10607](https://togithub.com/vimeo/psalm/pull/10607)
- Do not validate callable arguments in lenient contexts by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10601](https://togithub.com/vimeo/psalm/pull/10601)
- `readgzfile()` is impure by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10600](https://togithub.com/vimeo/psalm/pull/10600)
- Allow properties on intersections with enum interfaces by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10599](https://togithub.com/vimeo/psalm/pull/10599)
- `key_exists()` is an alias for `array_key_exists()` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10598](https://togithub.com/vimeo/psalm/pull/10598)
- Fix language server running with `opcache.save_comments=0` by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10614](https://togithub.com/vimeo/psalm/pull/10614)
- Report `MissingConstructor` for natively typed mixed properties by
[@&#8203;weirdan](https://togithub.com/weirdan) in
[https://github.com/vimeo/psalm/pull/10615](https://togithub.com/vimeo/psalm/pull/10615)

##### Internal changes

- Bump actions/cache from 3 to 4 by
[@&#8203;dependabot](https://togithub.com/dependabot) in
[https://github.com/vimeo/psalm/pull/10584](https://togithub.com/vimeo/psalm/pull/10584)
- Baseline update by [@&#8203;jorgsowa](https://togithub.com/jorgsowa)
in
[https://github.com/vimeo/psalm/pull/10593](https://togithub.com/vimeo/psalm/pull/10593)
- Re-work CheckTrivialExprVisitor by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10612](https://togithub.com/vimeo/psalm/pull/10612)
- Minor php-parser tweaks by
[@&#8203;edsrzf](https://togithub.com/edsrzf) in
[https://github.com/vimeo/psalm/pull/10605](https://togithub.com/vimeo/psalm/pull/10605)

#### New Contributors

- [@&#8203;jorgsowa](https://togithub.com/jorgsowa) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10593](https://togithub.com/vimeo/psalm/pull/10593)

**Full Changelog**:
vimeo/psalm@5.20.0...5.21.0

### [`v5.20.0`](https://togithub.com/vimeo/psalm/releases/tag/5.20.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.19.1...5.20.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Features

- report error for non-strict or empty comparison on truthy+falsy union
by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10502](https://togithub.com/vimeo/psalm/pull/10502)

##### Fixes

- Fix template, conditional array keys by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10568](https://togithub.com/vimeo/psalm/pull/10568)

**Full Changelog**:
vimeo/psalm@5.19.1...5.20.0

### [`v5.19.1`](https://togithub.com/vimeo/psalm/releases/tag/5.19.1)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.19.0...5.19.1)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Fixes

- Deprecated Template Classes are not ignored by
[@&#8203;psalm-suppress](https://togithub.com/psalm-suppress)
DeprecatedClass by
[@&#8203;samlitowitz](https://togithub.com/samlitowitz) in
[https://github.com/vimeo/psalm/pull/10518](https://togithub.com/vimeo/psalm/pull/10518)
- Implement \__set method in SimpleXMLElement stub by
[@&#8203;kthaler](https://togithub.com/kthaler) in
[https://github.com/vimeo/psalm/pull/10536](https://togithub.com/vimeo/psalm/pull/10536)
- Make getrandmax type more specific and unserialize to require
class-string by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10540](https://togithub.com/vimeo/psalm/pull/10540)
- Fix mb_get_info can return null - CI failing bc of reflection by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10543](https://togithub.com/vimeo/psalm/pull/10543)
- make basename & dirname return types more specific by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10545](https://togithub.com/vimeo/psalm/pull/10545)
- add support for extract to set variables for keyed arrays and respect
EXTR_SKIP by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10544](https://togithub.com/vimeo/psalm/pull/10544)
- remove redundat directory separator which caused "//" in path not
found errors by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10542](https://togithub.com/vimeo/psalm/pull/10542)
- Fix empty literal string becomes non-empty-string by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10499](https://togithub.com/vimeo/psalm/pull/10499)

#### New Contributors

- [@&#8203;samlitowitz](https://togithub.com/samlitowitz) made their
first contribution in
[https://github.com/vimeo/psalm/pull/10518](https://togithub.com/vimeo/psalm/pull/10518)
- [@&#8203;kthaler](https://togithub.com/kthaler) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10536](https://togithub.com/vimeo/psalm/pull/10536)

**Full Changelog**:
vimeo/psalm@5.19.0...5.20.0

### [`v5.19.0`](https://togithub.com/vimeo/psalm/releases/tag/5.19.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.18.0...5.19.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

#### What's Changed

##### Features

- Reduce memory consumption of caching and parallel processing without
igbinary by [@&#8203;sj-i](https://togithub.com/sj-i) in
[https://github.com/vimeo/psalm/pull/10532](https://togithub.com/vimeo/psalm/pull/10532)
- filter_input & filter_var return type more specific by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10498](https://togithub.com/vimeo/psalm/pull/10498)

##### Fixes

- strtok always returns a non-empty-string when it does not return false
by [@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10497](https://togithub.com/vimeo/psalm/pull/10497)
- Fix [#&#8203;10512](https://togithub.com/vimeo/psalm/issues/10512):
Fixed SessionUpdateTimestampHandlerInterface parameter names by
[@&#8203;zerkms](https://togithub.com/zerkms) in
[https://github.com/vimeo/psalm/pull/10524](https://togithub.com/vimeo/psalm/pull/10524)
- Fix [GH-10465](https://togithub.com/vimeo/psalm/issues/10465) by
[@&#8203;florisluiten](https://togithub.com/florisluiten) in
[https://github.com/vimeo/psalm/pull/10483](https://togithub.com/vimeo/psalm/pull/10483)
- Fix callable without args not handled correctly by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10500](https://togithub.com/vimeo/psalm/pull/10500)
- Add error when using readonly property in by-ref arg by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10505](https://togithub.com/vimeo/psalm/pull/10505)
- fix: [#&#8203;10496](https://togithub.com/vimeo/psalm/issues/10496)
[#&#8203;10503](https://togithub.com/vimeo/psalm/issues/10503) by
[@&#8203;ging-dev](https://togithub.com/ging-dev) in
[https://github.com/vimeo/psalm/pull/10508](https://togithub.com/vimeo/psalm/pull/10508)

#### New Contributors

- [@&#8203;florisluiten](https://togithub.com/florisluiten) made their
first contribution in
[https://github.com/vimeo/psalm/pull/10483](https://togithub.com/vimeo/psalm/pull/10483)

**Full Changelog**:
vimeo/psalm@5.18.0...5.19.0

### [`v5.18.0`](https://togithub.com/vimeo/psalm/releases/tag/5.18.0)

[Compare
Source](https://togithub.com/vimeo/psalm/compare/5.17.0...5.18.0)

<!-- Release notes generated using configuration in .github/release.yml
at 5.x -->

##### What's Changed

##### Features

- Add support for Override attribute by
[@&#8203;delolmo](https://togithub.com/delolmo) in
[https://github.com/vimeo/psalm/pull/10493](https://togithub.com/vimeo/psalm/pull/10493)

##### Fixes

- Fix [#&#8203;10460](https://togithub.com/vimeo/psalm/issues/10460) by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10464](https://togithub.com/vimeo/psalm/pull/10464)
- Emit AfterCodebasePopulatedEvent even on partial scans by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10457](https://togithub.com/vimeo/psalm/pull/10457)
- Small assertion fix by [@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10455](https://togithub.com/vimeo/psalm/pull/10455)
- Fix shaped array class string key combination by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10450](https://togithub.com/vimeo/psalm/pull/10450)
- Fix remaining POSIX-only absolute path detection by
[@&#8203;theodorejb](https://togithub.com/theodorejb) in
[https://github.com/vimeo/psalm/pull/10452](https://togithub.com/vimeo/psalm/pull/10452)
- dont combine empty string with numeric-string by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10459](https://togithub.com/vimeo/psalm/pull/10459)
- Fix type not equal when parent by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10477](https://togithub.com/vimeo/psalm/pull/10477)
- Use same parameter names in stubs by
[@&#8203;danog](https://togithub.com/danog) in
[https://github.com/vimeo/psalm/pull/10480](https://togithub.com/vimeo/psalm/pull/10480)
- fix false positive ArgumentTypeCoercion for callback param by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10454](https://togithub.com/vimeo/psalm/pull/10454)
- report error for invalid array key type by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10481](https://togithub.com/vimeo/psalm/pull/10481)
- fix literal int/string comparisons only using one literal by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10484](https://togithub.com/vimeo/psalm/pull/10484)
- add InvalidArgument error when passing false to true param by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10488](https://togithub.com/vimeo/psalm/pull/10488)
- Fix Uncaught RuntimeException: PHP Error: Uninitialized string offset
0 when $pattern is empty by
[@&#8203;iMu3ic](https://togithub.com/iMu3ic) in
[https://github.com/vimeo/psalm/pull/10489](https://togithub.com/vimeo/psalm/pull/10489)

##### Internal changes

- fix composer scripts running with inconsistent php versions by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10463](https://togithub.com/vimeo/psalm/pull/10463)
- update fidry/cpu-core-counter dependency by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10456](https://togithub.com/vimeo/psalm/pull/10456)
- fix psalm v4 hardcoded in tests by
[@&#8203;kkmuffme](https://togithub.com/kkmuffme) in
[https://github.com/vimeo/psalm/pull/10475](https://togithub.com/vimeo/psalm/pull/10475)

##### New Contributors

- [@&#8203;iMu3ic](https://togithub.com/iMu3ic) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10489](https://togithub.com/vimeo/psalm/pull/10489)
- [@&#8203;delolmo](https://togithub.com/delolmo) made their first
contribution in
[https://github.com/vimeo/psalm/pull/10493](https://togithub.com/vimeo/psalm/pull/10493)

**Full Changelog**:
vimeo/psalm@5.17.0...5.18.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/open-feature/php-sdk).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy45My4xIiwidXBkYXRlZEluVmVyIjoiMzcuMzMxLjAiLCJ0YXJnZXRCcmFuY2giOiJtYWluIn0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:feature The PR will be included in 'Features' section of the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Internal: non-strict checking leads to inconsistent behavior
8 participants