Skip to content

Incorrect "comparison will always evaluate to false" for comparison between static::class and <subclass>::class in class with @template #10498

Open

Description

@lkrms

Bug report

Works (see playground):

<?php

abstract class A
{
    public static function foo(): void
    {
        if (static::class === B::class) {
            printf("I'm a %s" . PHP_EOL, B::class);
        }
    }
}

class B extends A {}

Fails:

<?php

/**
 * @template T of object
 */
abstract class A
{
    public static function foo(): void
    {
        if (static::class === B::class) {
            printf("I'm a %s" . PHP_EOL, B::class);
        }
    }
}

/**
 * @extends A<C>
 */
class B extends A {}

class C {};

Code snippet that reproduces the problem

https://phpstan.org/r/79f71be1-69bd-40a6-8bf3-ed36806ba226

Expected output

PHPStan shouldn't report a comparison between static::class and the name of a subclass as "always false", whether templates are in play or not.

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

No response

Activity

  1. added this to the Easy fixes milestone on Jan 28, 2024
  2. phpstan-bot commented on Sep 26, 2024

    @phpstan-bot
    Contributor

    @lkrms After the latest push in 2.0.x, PHPStan now reports different result with your code snippet:

    @@ @@
    -10: Strict comparison using === between class-string<static(A<T of object>)> and 'B' will always evaluate to false.
    +10: Strict comparison using === between class-string<static(A<T of object (class A, argument)>)> and 'B' will always evaluate to false.
    Full report
    Line Error
    10 Strict comparison using === between class-string<static(A<T of object (class A, argument)>)> and 'B' will always evaluate to false.
  3. added a commit that references this issue on Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions