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

LessSpecificReturnStatement + MoreSpecificReturnType reported together #2875

Closed
bendavies opened this issue Feb 24, 2020 · 10 comments
Closed
Labels

Comments

@bendavies
Copy link
Contributor

See: https://psalm.dev/r/4c0bab583c

If we change line 28 to
@return (T&Baz)|null
(switching Baz and T), then there are no errors.

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/4c0bab583c
<?php

class Foo
{

    /**
     * @psalm-var class-string
     * @var string 
     */
    private $class = Bar::class;

  	/**
     * @return class-string
     */
    public function getClass(): string
    {
        return $this->class;
    }
}

interface Baz {}

class Bar implements Baz
{
    /**
     * @template T
     * @psalm-param class-string<T> $class
     * @return (Baz&T)|null
     */
    public function instantiator(string $class): ?Baz
    {
		return rand(0, 1) ? new $class() : null;
    }
}

$foo = new Foo();
$bar = new Bar();
$bar->instantiator($foo->getClass());
Psalm output (using commit 234a6ba):

INFO: LessSpecificReturnStatement - 32:10 - The type 'T:fn-bar::instantiator as object|null' is more general than the declared return type 'Baz&(T:fn-bar::instantiator as object)|null' for Bar::instantiator

INFO: MoreSpecificReturnType - 28:16 - The declared return type 'Baz&(T:fn-bar::instantiator as object)|null' for Bar::instantiator is more specific than the inferred return type 'T:fn-bar::instantiator as object|null'

@weirdan
Copy link
Collaborator

weirdan commented Feb 24, 2020

Order-dependence is unexpected, but wouldn't it make more sense to declare the types like this: https://psalm.dev/r/462ae2c353

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/462ae2c353
<?php

class Foo
{

    /**
     * @psalm-var class-string
     * @var string 
     */
    private $class = Bar::class;

  	/**
     * @return class-string
     */
    public function getClass(): string
    {
        return $this->class;
    }
}

interface Baz {}

class Bar implements Baz
{
    /**
     * @template T of Baz
     * @psalm-param class-string<T> $class
     * @return ?T
     */
    public function instantiator(string $class): ?Baz
    {
		return rand(0, 1) ? new $class() : null;
    }
}

$foo = new Foo();
$bar = new Bar();
$bar->instantiator($foo->getClass());
Psalm output (using commit 712806b):

ERROR: ArgumentTypeCoercion - 38:20 - Argument 1 of Bar::instantiator expects class-string<Baz>, parent type class-string provided

@bendavies
Copy link
Contributor Author

i wasn't aware of that syntax. thanks

@muglug muglug added the bug label Feb 24, 2020
@muglug
Copy link
Collaborator

muglug commented Feb 24, 2020

Yes, order-dependence is still a bug

@bendavies
Copy link
Contributor Author

seems phpstan doesn't like @template T of Foo unfortunately. (i run both)

@weirdan
Copy link
Collaborator

weirdan commented Feb 24, 2020

@muglug
Copy link
Collaborator

muglug commented Feb 25, 2020

distilled down, these should both be errors: https://psalm.dev/r/7c42967494

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/7c42967494
<?php

interface Bar {}
interface Baz {}

/**
 * @template T
 * @psalm-param class-string<T> $class
 * @return T&Baz
 */
function returnsTemplatedIntersection(string $class) {
  return new $class();
}

/**
 * @return Bar&Baz
 */
function returnsIntersection(Bar $bar) {
  return $bar;
}
Psalm output (using commit f9f49f1):

ERROR: InvalidReturnStatement - 19:10 - The type 'Bar' does not match the declared return type 'Bar&Baz' for returnsIntersection

ERROR: InvalidReturnType - 16:12 - The declared return type 'Bar&Baz' for returnsIntersection is incorrect, got 'Bar'

@bendavies
Copy link
Contributor Author

Works for me: phpstan.org/r/c5b43fd7-f415-43fa-aacf-159a2a3123c8

huh, thanks. i got an error. i'll look into it another time.

@muglug muglug closed this as completed in 35c1670 Feb 27, 2020
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