Fix phpstan/phpstan#11054: [NAN] === mixed is always evaluated as false#5321
Conversation
- Override getFiniteTypes() in ConstantFloatType to return [] for NAN values
- This prevents TypeSpecifier from subtracting array{NAN} from mixed in the
false branch of === checks, since NAN-containing arrays can still be
identical when they share the same zval (e.g., class constants)
- New regression test in tests/PHPStan/Rules/Comparison/data/bug-11054.php
| namespace Bug11054; | ||
|
|
||
| class XXX { | ||
| public const DEF_VALUE = [NAN]; |
There was a problem hiding this comment.
Add another test using INF instead of NAN
There was a problem hiding this comment.
Both background tasks confirmed complete. All done — the commit with INF test cases has been pushed to the PR branch.
Adds test coverage for INF (as opposed to NAN) in array constant comparisons. Unlike NAN, INF === INF is true in PHP, so type narrowing correctly eliminates the type after the first comparison. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
I find weird to have not consistency between getScalaraTypes, getScalarValues and getFiniteTypes. |
|
Please add https://phpstan.org/r/45b081b0-e71e-43b2-99cd-a14590ea6687 from the linked issue. After this PR it seems still unfixed, I expect 4x always false reported (as cmp against |
|
Please, as always requested multiples times, don't comment on closed PR and open dedicated issues. We fixed a bug, an wrong "Always false" message. |
…se (phpstan#5321) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
PHPStan incorrectly reported
Strict comparison using === between mixed and array{NAN} will always evaluate to falsewhen a variable of typemixedwas compared against multiple class constants containing[NAN]. After the first=== CONST_Acheck, PHPStan narrowed the type by subtractingarray{NAN}, causing subsequent comparisons against other[NAN]constants to be flagged as always false.Changes
getFiniteTypes()insrc/Type/Constant/ConstantFloatType.phpto return[]for NAN valuestests/PHPStan/Rules/Comparison/data/bug-11054.phptestBug11054intests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.phpRoot cause
ConstantFloatType(NAN)inheritedgetFiniteTypes()fromConstantScalarTypeTraitwhich returned[$this]. This causedConstantArrayTypecontaining NAN to also report a single finite type. TheTypeSpecifierusesgetFiniteTypes()to decide whether to narrow (subtract) a type in the false branch of===checks. For NAN-containing arrays, this narrowing is incorrect because in PHP, two references to the same[NAN]array (e.g., class constants) ARE identical via===(same zval), even though structurally different[NAN]arrays are not. By returning[]fromgetFiniteTypes()for NAN, the false-branch narrowing is skipped, while the true-branch narrowing still works via theisConstantValue()fallback path.Test
The regression test verifies that comparing a
mixedparameter against multiple class constants containing[NAN]produces no false-positive "always false" errors.Fixes phpstan/phpstan#11054