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

[4.25.0] InvalidArgument for result of a method with a static return type #8330

Closed
vudaltsov opened this issue Jul 28, 2022 · 8 comments · Fixed by #8335
Closed

[4.25.0] InvalidArgument for result of a method with a static return type #8330

vudaltsov opened this issue Jul 28, 2022 · 8 comments · Fixed by #8335

Comments

@vudaltsov
Copy link
Contributor

vudaltsov commented Jul 28, 2022

<?php

declare(strict_types=1);

namespace HappyInc;

abstract class A
{
}

final class B extends A
{
    public static function create(): static
    {
        return new self();
    }
}

final class Service
{
    public function do(): void
    {
        $this->acceptA(B::create());
    }

    private function acceptA(A $_a): void
    {
    }
}

gives

ERROR: InvalidArgument - src/A.php:23:24 - Argument 1 of HappyInc\Service::acceptA expects HappyInc\A, HappyInc\Service provided (see https://psalm.dev/004)
        $this->acceptA(B::create());

in 4.25.0.

By the way, for some reason https://psalm.dev/r/6081a71dec says "No issues!".

@psalm-github-bot
Copy link

psalm-github-bot bot commented Jul 28, 2022

I found these snippets:

https://psalm.dev/r/6081a71dec
<?php

declare(strict_types=1);

namespace HappyInc;

abstract class A
{
}

final class B extends A
{
    public static function create(): static
    {
        return new self();
    }
}

final class Service
{
    public function do(): void
    {
        $this->acceptA(B::create());
    }

    private function acceptA(A $_a): void
    {
    }
}
Psalm output (using commit 7c4228f):

No issues!

@vudaltsov
Copy link
Contributor Author

vudaltsov commented Jul 28, 2022

Oh, I see, psalm.dev is at 7c4228f, not d7cd84c.

@orklah
Copy link
Collaborator

orklah commented Jul 28, 2022

Hey @someniatko , it could be a result of #8249. Would you mind taking a look?

@VincentLanglet
Copy link
Contributor

VincentLanglet commented Jul 28, 2022

I have the same issue with the following code https://psalm.dev/r/3765f8a43d

If you need a reproducer, you can try
https://github.com/sonata-project/SonataAdminBundle/blob/4.x/src/FieldDescription/TypeGuesserChain.php#L57
Which has two more issue since 4.25

ERROR: MoreSpecificReturnType - src/FieldDescription/TypeGuesserChain.php:57:73 - The declared return type 'Symfony\Component\Form\Guess\TypeGuess|null' for Sonata\AdminBundle\FieldDescription\TypeGuesserChain::guess is more specific than the inferred return type 'Symfony\Component\Form\Guess\Guess&static|null' (see https://psalm.dev/070)
    public function guess(FieldDescriptionInterface $fieldDescription): ?TypeGuess


ERROR: LessSpecificReturnStatement - src/FieldDescription/TypeGuesserChain.php:69:16 - The type 'Symfony\Component\Form\Guess\Guess&static|null' is more general than the declared return type 'Symfony\Component\Form\Guess\TypeGuess|null' for Sonata\AdminBundle\FieldDescription\TypeGuesserChain::guess (see https://psalm.dev/129)
        return TypeGuess::getBestGuess($guesses);

If it require a rework of static, might be worth taking a look at #5938 too.

@psalm-github-bot
Copy link

psalm-github-bot bot commented Jul 28, 2022

I found these snippets:

https://psalm.dev/r/3765f8a43d
<?php

abstract class Guess 
{
    /**
     * @param static[] $guesses An array of guesses
     *
     * @return static|null
     */
    public static function getBestGuess(array $guesses)
    {
        return $guesses[0] ?? null;
    }
}

class TypeGuess extends Guess
{
}

class FooFoo
{
    public function guess(TypeGuess $object): ?TypeGuess
    {
       
        return TypeGuess::getBestGuess([$object]);
    }
}
Psalm output (using commit 7c4228f):

ERROR: ArgumentTypeCoercion - 25:40 - Argument 1 of TypeGuess::getBestGuess expects array<array-key, TypeGuess&static>, parent type array{TypeGuess} provided

@someniatko
Copy link
Contributor

someniatko commented Jul 28, 2022

@orklah I will take a look tomorrow. My suspect is hasStaticInType() returned false for some reason, but that's really strange, there should be enough tests already written, one of which should have caught this.

@AndrolGenhald
Copy link
Collaborator

AndrolGenhald commented Jul 28, 2022

@vudaltsov does it still happen if you return new static() instead of new self()? Maybe that's the culprit?

@vudaltsov
Copy link
Contributor Author

vudaltsov commented Jul 28, 2022

@AndrolGenhald, no, it gives the same error. Anyway, in a final class it's valid to return new self in a : static method.

someniatko added a commit to someniatko/psalm that referenced this issue Jul 29, 2022
…pped in ExistingAtomicStaticCallAnalyzer#hasStaticInType()
AndrolGenhald added a commit that referenced this issue Jul 29, 2022
#8330 - take into account that `static` type may have been unwrapped in `hasStaticInType()`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants