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

Psalm 4.5 and later ignores assertions of instanceof Interface #5236

Closed
ArtemGoutsoul opened this issue Feb 16, 2021 · 7 comments
Closed

Psalm 4.5 and later ignores assertions of instanceof Interface #5236

ArtemGoutsoul opened this issue Feb 16, 2021 · 7 comments
Labels

Comments

@ArtemGoutsoul
Copy link
Contributor

Here's an example:
https://psalm.dev/r/863377401f

This worked in 4.4.1

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/863377401f
<?php

function get_header(bool $param = false): ArrayIterator|HeaderInterface
{
    if ($param) return new ArrayIterator();
    else return new Header();
}

class Header implements HeaderInterface
{
    public function doStuff(): void {}
}

interface HeaderInterface
{
    public function doStuff(): void;
}

$header = get_header();
assert($header instanceof HeaderInterface);
$header->doStuff();
Psalm output (using commit 7b24552):

ERROR: UndefinedMethod - 21:10 - Method ArrayIterator::doStuff does not exist

@weirdan
Copy link
Collaborator

weirdan commented Feb 16, 2021

It appears assert removes HeaderInterface in this case 😮 : https://psalm.dev/r/50cf76d7eb

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/50cf76d7eb
<?php

function get_header(bool $param = false): ArrayIterator|HeaderInterface
{
    if ($param) return new ArrayIterator();
    else return new Header();
}

class Header implements HeaderInterface
{
    public function doStuff(): void {}
}

interface HeaderInterface
{
    public function doStuff(): void;
}

$header = get_header();
/** @psalm-trace $header */;
assert($header instanceof HeaderInterface);
/** @psalm-trace $header */;
$header->doStuff();
Psalm output (using commit 7b24552):

INFO: Trace - 20:28 - $header: ArrayIterator<array-key, mixed>|HeaderInterface

INFO: Trace - 22:28 - $header: ArrayIterator<array-key, mixed>

ERROR: UndefinedMethod - 23:10 - Method ArrayIterator::doStuff does not exist

@weirdan weirdan added the bug label Feb 16, 2021
@ArtemGoutsoul
Copy link
Contributor Author

ArtemGoutsoul commented Feb 17, 2021

@weirdan Should have tried the trace too, thanks for the example! :)

Kinda funny regression, assert should have caused ArrayIterator|HeaderInterface to become (not sure how to write it): HeaderInterface for sure AND possibly ArrayIterator, and instead it somehow just dropped HeaderInterface

@muglug
Copy link
Collaborator

muglug commented Feb 24, 2021

Simplified: https://psalm.dev/r/84f2bd0e92

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/84f2bd0e92
<?php

class SomeClass {}
interface SomeInterface {
	public function doStuff(): void;
}

function takesAorB(SomeClass|SomeInterface $some): void {
    if ($some instanceof SomeInterface) {
        $some->doStuff();
    }
}
Psalm output (using commit cafbdb6):

ERROR: UndefinedMethod - 10:16 - Method SomeClass::doStuff does not exist

@muglug
Copy link
Collaborator

muglug commented Feb 24, 2021

Sorry, this is a pretty bad bug and should have been caught in a test

@muglug muglug closed this as completed in f8cbb22 Feb 24, 2021
This was referenced Mar 15, 2021
This was referenced Mar 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants