🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

Object property narrowing leaks out of a previous if when a 2-case enum is narrowed with !== #14807

Description

@momala454

Bug report

When two if statements reuse the same left-hand condition $enum !== Case::X (with a 2-case enum), and the first if additionally narrows an object property via && $obj->prop === true, PHPStan incorrectly carries that property narrowing over to the second if. It then reports $obj->prop === false in the second if as always false.

This is a false positive: the first if can be skipped purely because the enum condition was false, in which case the property keeps its real (unknown) bool value. The second branch is therefore reachable.

The issue requires all of the following — removing any one of them makes the false positive disappear:

  • a 2-case enum narrowed with !== (using ===, an int, or a plain bool flag does not reproduce);
  • the value being narrowed must be an object property (a local bool variable does not reproduce);
  • the same left-hand enum condition reused in both if statements.

It reproduces without bleeding edge, and on both 2.2.2 (stable) and 2.2.x-dev.

Code snippet that reproduces the problem

https://phpstan.org/r/0852b450-c2e2-4b15-84e4-afa9e4ac1616

Expected output

No errors.

Actual output
Both errors are reported on the second if:

Result of && is always false. (booleanAnd.alwaysFalse)
Strict comparison using === between true and false will always evaluate to false. (identical.alwaysFalse)

Did PHPStan help you today? Did it make you happy in any way?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions