Skip to content

Strict comparison between int and 0 will always evaluate to false #9804

Description

@kirill-voronov

Bug report

Hello!
I can't understand what's wrong with the code and even more I disagree with error message itself.
Strict comparison using === between int<min, -1>|int<1, max> and 0 will always evaluate to false - this is not true because 0 is also integer type.

<?php
declare(strict_types=1);

class Test
{
    public function error(?string $someString): void
    {
        // Line below is the only difference to "pass" method
        if (!$someString) {
            return;
        }

        // Strict comparison using === between int<min, -1>|int<1, max> and 0 will always evaluate to false.
        $firstLetterAsInt = (int)substr($someString, 0, 1);
        if ($firstLetterAsInt === 0) {
            return;
        }
    }

    public function pass(?string $someString): void
    {
        // Line below is the only difference to "error" method
        if ($someString === null) {
            return;
        }

        // All ok
        $firstLetterAsInt = (int)substr($someString, 0, 1);
        if ($firstLetterAsInt === 0) {
            return;
        }
    }
}

I've found similar issue here #2889 it's not seem to be resolved but closed.

Code snippet that reproduces the problem

https://phpstan.org/r/f6379c30-8929-46a4-8d5e-ab06e30c55f2

Expected output

No errors on line 15

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

Yes, PHPStan is a great tool.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions