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

Error reported using static create method with generics #10945

Closed
andriokha opened this issue Apr 27, 2024 · 2 comments
Closed

Error reported using static create method with generics #10945

andriokha opened this issue Apr 27, 2024 · 2 comments

Comments

@andriokha
Copy link

andriokha commented Apr 27, 2024

Bug report

I have a decorator that accepts a class name and uses a static create method and I can't get it to pass phpstan analysis. I've reduced down what I'm trying to do in the given example, and it seems to work fine if I call the constructor directly, but fails when I call the static method.

Code snippet that reproduces the problem

https://phpstan.org/r/092a3bd0-089a-48e0-944a-dcfd4f341583

Expected output

I'd expect it to pass analysis without any errors, but A::getDecoratorFail() fails with

Method A::getDecoratorFail() should return DecoratorInterface<T> but returns DecoratorInterface<mixed>.

Did PHPStan help you today? Did it make you happy in any way?

It helped me today, and yesterday, and will help me tomorrow, thank you (:

@ondrejmirtes
Copy link
Member

It doesn't make much sense to reference class-level @template above a static method. Because you're not calling Decorator<Foo>::create($class), you're just calling Decorator::create($class) and the T is unknown.

This works: https://phpstan.org/r/5a5b826c-7dea-44ed-aa7f-f09a43223920

@andriokha
Copy link
Author

Thank you for such a prompt reply and a solution to my problem! ❤️

It's confusing to me that a constructor works with the class-level template type but not a static method - I appreciate a constructor's not static, but they're both called without an instance and return an instance (with phpstan inferring the type from the argument). Perhaps generics in other languages are muddying the waters for me slightly, eg. you'd use the same template parameter for the constructor and a static method in C++ IIUC.

It seems the takeaway is that with phpstan a class-level template only covers an instance of the class, rather than the class as a whole.

Thanks again, wasn't expecting a reply on the weekend, hope you get an opportunity to relax!

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

2 participants