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

Internal error when using trait in abstract class with abstract __invoke() method. #4210

Closed
ptomulik opened this issue Sep 18, 2020 · 5 comments

Comments

@ptomulik
Copy link
Contributor

This started with 3.15 (3.14.2 seems to still work well).

https://psalm.dev/r/15fea19e9a

The following conditions seem to be crucial:

  • function testFunc(callable $func) : void - the parameter is declared as callable (either by type hinting or in docblock),
  • abstract public function __invoke() : void; - this declaration is present in TestTrait,
  • abstract public function __invoke() : void; - this declaration is not present in TestClass
  • testFunc($this); - this invocation is present within the trait's apply() method,
  • abstract class TestClass { // ... - the class must be declared as abstract
  • use TestTrait - trait is used in TestClass,

If any of the above is not meet, then there is no internal error.

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/15fea19e9a
<?php

function testFunc(callable $func) : void
{
    $func();
}

trait TestTrait
{
    abstract public function __invoke() : void;

    public function apply() : void
    {
        testFunc($this);
    }
}

abstract class TestClass {
    use TestTrait;
}
Psalm encountered an internal error:

/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Methods.php: $storage should not be null for TestClass::__invoke

@ptomulik
Copy link
Contributor Author

For the moment the workaround seems to be repeating the abstract declaration of __invoke() in TestClass.

https://psalm.dev/r/14ad4df24d

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/14ad4df24d
<?php

function testFunc(callable $func) : void
{
    $func();
}

trait TestTrait
{
    abstract public function __invoke() : void;

    public function apply() : void
    {
        testFunc($this);
    }
}

abstract class TestClass
{
    use TestTrait;
    abstract public function __invoke() : void;
}
Psalm output (using commit 5db75df):

No issues!

@ptomulik
Copy link
Contributor Author

The internal error also appear if the abstract __invoke() is moved to an interface implemented by TestClass

https://psalm.dev/r/ed9e55f42a

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/ed9e55f42a
<?php

function testFunc(callable $func) : void
{
    $func();
}

trait TestTrait
{
    public function apply() : void
    {
        testFunc($this);
    }
}

interface TestInterface
{
    public function __invoke() : void;
}

abstract class TestClass implements TestInterface
{
    use TestTrait;
}
Psalm encountered an internal error:

/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Methods.php: $storage should not be null for TestClass::__invoke

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

No branches or pull requests

1 participant