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

first-class callables type is not inferred if it is an inherited static method #8363

Closed
someniatko opened this issue Aug 3, 2022 · 5 comments · Fixed by #8370
Closed

first-class callables type is not inferred if it is an inherited static method #8363

someniatko opened this issue Aug 3, 2022 · 5 comments · Fixed by #8370

Comments

@someniatko
Copy link
Contributor

refs #6412

it seems the support for the first-class callables is not yet complete:
https://psalm.dev/r/bbc03df04c

@psalm-github-bot
Copy link

I found these snippets:

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

/** @template T */
class Holder
{
    /** @param T $value */
    public function __construct(public $value) {}
}

abstract class A
{
    final public function __construct(public int $i) {}
    
    /** @return Holder<static> */
    public static function create(int $i): Holder
    {
        return new Holder(new static($i));
    }
}

class C extends A
{
}

$cl1 = C::create(...);
/** @psalm-trace $cl1 */ ;

$cl2 = fn(int $i): Holder => C::create($i);
/** @psalm-trace $cl2 */ ;
Psalm output (using commit 24f7920):

INFO: Trace - 26:26 - $cl1: Closure

INFO: Trace - 29:26 - $cl2: impure-Closure(int):Holder<C>

INFO: UnusedVariable - 25:1 - $cl1 is never referenced or the value is not used

INFO: UnusedVariable - 28:1 - $cl2 is never referenced or the value is not used

@someniatko someniatko changed the title [v5] first-class callables type is not inferred if it is an overridden static method first-class callables type is not inferred if it is an overridden static method Aug 3, 2022
@someniatko
Copy link
Contributor Author

someniatko commented Aug 4, 2022

Found a much easier reproducer: https://psalm.dev/r/428333f418

Basically it doesn't work properly if it doesn't find a static method in the class itself (e.g. if it's an inherited method)

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/428333f418
<?php

abstract class A
{
    public function foo(int $i): string
    {
        return (string) $i;
    }
}

class C extends A {}

/** @param \Closure(int):string $_ */
function takesIntToString(\Closure $_): void {}

takesIntToString(C::foo(...));
Psalm output (using commit 24f7920):

INFO: MixedArgumentTypeCoercion - 16:18 - Argument 1 of takesIntToString expects Closure(int):string, parent type Closure provided

@someniatko someniatko changed the title first-class callables type is not inferred if it is an overridden static method first-class callables type is not inferred if it is an inherited static method Aug 4, 2022
@someniatko
Copy link
Contributor Author

@AndrolGenhald I found a fix for the "easier" reproducer (see the message above), but I'll need your help for fixing the original case. I'll submit a PR shortly.

someniatko added a commit to someniatko/psalm that referenced this issue Aug 4, 2022
someniatko added a commit to someniatko/psalm that referenced this issue Aug 4, 2022
someniatko added a commit to someniatko/psalm that referenced this issue Aug 4, 2022
@AndrolGenhald
Copy link
Collaborator

I'm afraid I'm not very familiar with any of this, it looks like first class callable support was added in #7113 so maybe @trowski or @orklah would be better help.

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

Successfully merging a pull request may close this issue.

2 participants