Skip to content

Fix phpstan/phpstan#11054: [NAN] === mixed is always evaluated as false#5321

Merged
staabm merged 2 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-2yr80xg
Mar 29, 2026
Merged

Fix phpstan/phpstan#11054: [NAN] === mixed is always evaluated as false#5321
staabm merged 2 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-2yr80xg

Conversation

@phpstan-bot
Copy link
Copy Markdown
Collaborator

Summary

PHPStan incorrectly reported Strict comparison using === between mixed and array{NAN} will always evaluate to false when a variable of type mixed was compared against multiple class constants containing [NAN]. After the first === CONST_A check, PHPStan narrowed the type by subtracting array{NAN}, causing subsequent comparisons against other [NAN] constants to be flagged as always false.

Changes

  • Overrode getFiniteTypes() in src/Type/Constant/ConstantFloatType.php to return [] for NAN values
  • Added regression test in tests/PHPStan/Rules/Comparison/data/bug-11054.php
  • Added test method testBug11054 in tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php

Root cause

ConstantFloatType(NAN) inherited getFiniteTypes() from ConstantScalarTypeTrait which returned [$this]. This caused ConstantArrayType containing NAN to also report a single finite type. The TypeSpecifier uses getFiniteTypes() 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 [] from getFiniteTypes() for NAN, the false-branch narrowing is skipped, while the true-branch narrowing still works via the isConstantValue() fallback path.

Test

The regression test verifies that comparing a mixed parameter against multiple class constants containing [NAN] produces no false-positive "always false" errors.

Fixes phpstan/phpstan#11054

- 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];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add another test using INF instead of NAN

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@staabm staabm requested a review from VincentLanglet March 29, 2026 08:13
@VincentLanglet
Copy link
Copy Markdown
Contributor

I find weird to have not consistency between getScalaraTypes, getScalarValues and getFiniteTypes.
But I made multiple tried and didn't see bad impact on this change. (while changing Scalar method would have)

@staabm staabm merged commit 43fca98 into phpstan:2.1.x Mar 29, 2026
656 of 657 checks passed
@staabm staabm deleted the create-pull-request/patch-2yr80xg branch March 29, 2026 10:47
@mvorisek
Copy link
Copy Markdown
Contributor

mvorisek commented Mar 29, 2026

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 NAN or array containing NAN is always false).

@VincentLanglet
Copy link
Copy Markdown
Contributor

VincentLanglet commented Mar 29, 2026

Please, as always requested multiples times, don't comment on closed PR and open dedicated issues.
Especially now because the phpstan-bot is mainly working with the snippet of the first message of the issue and solve problems one by one.

We fixed a bug, an wrong "Always false" message.
What you're asking is a feature request, an extra "Always false" message.

phpstan-bot added a commit to phpstan-bot/phpstan-src that referenced this pull request Apr 7, 2026
…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>
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

Successfully merging this pull request may close these issues.

4 participants