Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

instanceof redundant for class, but not for interface #7341

Open
donquixote opened this issue Jan 8, 2022 · 4 comments
Open

instanceof redundant for class, but not for interface #7341

donquixote opened this issue Jan 8, 2022 · 4 comments

Comments

@donquixote
Copy link
Contributor

psalm is inconsistent in when it says "RedundantCondition" on instanceof checks.

https://psalm.dev/r/377cb86ce7

interface I {}
class C {}

/**
 * @param I $o
 */
function fI(I $o): void {
    // Not redundant?
    if ($o instanceof I) {
        print 'yes';
    }
}

/**
 * @param C $o
 */
function fC(C $o): void {
    // ERROR: RedundantCondition - 20:9 - Type C for $o is always C
    if ($o instanceof C) {
        print 'yes';
    }
}
@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/377cb86ce7
<?php

interface I {}
class C {}

/**
 * @param I $o
 */
function fI(I $o): void {
    // Not redundant?
    if ($o instanceof I) {
        print 'yes';
    }
}

/**
 * @param C $o
 */
function fC(C $o): void {
    // ERROR: RedundantCondition - 20:9 - Type C for $o is always C
    if ($o instanceof C) {
        print 'yes';
    }
}
Psalm output (using commit 762ef8d):

ERROR: RedundantCondition - 21:9 - Type C for $o is always C

@orklah
Copy link
Collaborator

orklah commented Jan 8, 2022

The difference is here:

&& !$new_type_has_interface

In your snippet, it doesn't matter that much, but the RedundantCondition is a false positive because of this: https://psalm.dev/r/3bd23090dd

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/3bd23090dd
<?php

interface I {}
class C {}
class B extends C{}
class D extends C{}

class A{
    /**
     * @param C $o
     * @param class-string<C> $c
     */
    public static function C(C $o, string $c): void {
        // ERROR: RedundantCondition - 20:9 - Type C for $o is always C
        if ($o instanceof $c) {
            print 'yes';
        }
    }
}

$b = new B();

A::C($b, D::class);
Psalm output (using commit b941078):

ERROR: RedundantCondition - 15:13 - Type C for $o is always C

@orklah orklah added the bug label Jan 8, 2022
@orklah
Copy link
Collaborator

orklah commented Jan 8, 2022

I actually worked on a very similar issue very close to this code: #6739

In fact, when dropping the && !$new_type_has_interface I linked above, it's my test that fails...

Not sure why there are two conditions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants