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 using generics with class-string and proxy #4803

Closed
franmomu opened this issue Apr 4, 2021 · 7 comments
Closed

Error using generics with class-string and proxy #4803

franmomu opened this issue Apr 4, 2021 · 7 comments

Comments

@franmomu
Copy link

franmomu commented Apr 4, 2021

Bug report

So the idea is that having a function that receives a class-string of an object or a class-string of a Proxy of that object and it returns the class-string of the object.

Ref: #4802

Code snippet that reproduces the problem

https://phpstan.org/r/94be9c1a-f99d-4403-afb4-8f038433aaf1

Expected output

No issues

@ondrejmirtes ondrejmirtes added this to the Generics milestone Apr 5, 2021
@ondrejmirtes
Copy link
Member

I don't know how to fix this one. The root issue is this: https://phpstan.org/r/052a2f58-8316-4135-94d0-36a1c4525172

The problem is that this behaviour is correct. It's kind of undetermined what should happen when we have Proxy<T>|T and we pass Proxy<stdClass> to it. See - we need to infer T from that.

The inferring type is a union. From the Proxy<T> part we infer that T is stdClass.

From the T part we infer that T is Proxy<stdClass>. That's why the result is Proxy<stdClass>|stdClass and not just stdClass.

There isn't anything that says that Proxy<T> has to be greedily applied to Proxy<stdClass> and that the rest of the union type (|T) should be thrown away.

@ondrejmirtes
Copy link
Member

BTW this was a similar problem #3623 but easier to fix (phpstan/phpstan-src@a1b7b38).

@phpstan-bot
Copy link
Contributor

@franmomu After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
-34: Method Client::getRealClass() should return class-string<T of object> but returns class-string<Proxy<T of object>|T of object>.
+No errors

@phpstan-bot
Copy link
Contributor

@ondrejmirtes After the latest commit in dev-master, PHPStan now reports different result with your code snippet:

@@ @@
 15: Function Bug4803\resolve() should return T of object but return statement is missing.
-30: Dumped type: Bug4803\Proxy<T of object (method Bug4803\Foo::doFoo(), argument)>|T of object (method Bug4803\Foo::doFoo(), argument)
+30: Dumped type: T of object (method Bug4803\Foo::doFoo(), argument)
 30: Method Bug4803\Foo::doFoo() should return T of object but return statement is missing.
-37: Dumped type: Bug4803\Proxy<stdClass>|stdClass
+37: Dumped type: stdClass
 44: Dumped type: stdClass
-51: Dumped type: Bug4803\Proxy<stdClass>|stdClass
+51: Dumped type: stdClass
Full report
Line Error
15 Function Bug4803\resolve() should return T of object but return statement is missing.
30 Dumped type: T of object (method Bug4803\Foo::doFoo(), argument)
30 Method Bug4803\Foo::doFoo() should return T of object but return statement is missing.
37 Dumped type: stdClass
44 Dumped type: stdClass
51 Dumped type: stdClass

@ondrejmirtes
Copy link
Member

Fixed by: phpstan/phpstan-src@3be90f0

@franmomu
Copy link
Author

Nice! thank you

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants