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

Unknown type within template with @param array<T> #4258

Open
sanmai opened this issue Sep 29, 2020 · 3 comments
Open

Unknown type within template with @param array<T> #4258

sanmai opened this issue Sep 29, 2020 · 3 comments

Comments

@sanmai
Copy link
Contributor

sanmai commented Sep 29, 2020

https://psalm.dev/r/508b2bc5aa

/**
 * @template T
 */
interface ItemList
{
    /**
     * @param array<T> $list
     * @return static<T>
     */
    public static function withList(array $list);
}

ERROR: UndefinedDocblockClass - 10:15 - Docblock-defined class or interface T does not exist

All the while other uses of T are not reported. It's either this one use in @param is not an error, or other uses must be errors too.

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/508b2bc5aa
<?php
/**
 * @template T
 */
interface ItemList
{
    /**
     * @param array<T> $list
     * @return static<T>
     */
    public static function withList(array $list);
}
Psalm output (using commit 19f88a2):

ERROR: UndefinedDocblockClass - 8:15 - Docblock-defined class or interface T does not exist

@weirdan weirdan added the bug label Sep 29, 2020
@jost125
Copy link

jost125 commented Nov 2, 2020

From what I was googling, it looks, that psalm does not inherit template T for static methods. There is more (closed) issues like that.

The solution here is to "repeat" template here, like this:

/**
 * @template T
 */
interface ItemList
{
    /**
     * @template T2
     * @param array<T2> $list
     * @return static<T2>
     */
    public static function withList(array $list);
}

But I have another problem with this. Phpstan and psalm are imcompatible with this. Phpstan inherits it.

You can write it this way in phpsan as well, but it behaves diferently.

Result is, that you cannot use both phpstan and psalm in single project with generics used in static functions.

Here is releated issue in phpstan (about incompability) by @muglug
phpstan/phpstan#2738

Here is example of releated (closed) issue in psalm
#2751

It would be great, if both tools would have same behavior for this.

@thunderer
Copy link

@jost125 from what I understand @muglug reenabled templates inheritance on static methods in #2751, was it disabled somewhere between February and now as in that linked PHPStan issue? I'm trying to get thunderer/Platenum#24 to work with Psalm templates so that you can restrict the available values on the type level. Enumerations in PHP are implemented through Multiton, so the classes rely on static methods a lot. I would like to "specify" template values in the outermost classes (T of self::*) which would then propagate back to the EnumTrait.

How does your example above work? Is it possible to link these templates like @psalm-template T2 of T?

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

No branches or pull requests

5 participants