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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inferring template types in ClosureType #921

Merged

Conversation

canvural
Copy link
Contributor

This PR fixes an issue that can be seen here and here.

Since there are separate types as ClosureType and CallableType I think it makes sense for ClosureType to only infer template types from it's own kind. Cause nothing else can really be a closure. When callable is used instead of Closure in the playground examples, it'll still be inferred as mixed.

I hope this fix makes sense. If you prefer any other way that fixes the issues (both in tests and in playground links) I can adjust to that 馃憤馃徑

@@ -334,7 +334,7 @@ public function inferTemplateTypes(Type $receivedType): TemplateTypeMap
return $receivedType->inferTemplateTypesOn($this);
}

if ($receivedType->isCallable()->no()) {
if ($receivedType->isCallable()->no() || ! $receivedType instanceof self) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, what about the same change and test in CallableType.php? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I thought that can be a valid use case? new Foo which is ObjectType, can be callable, and we should try to infer template types. I did this for ClosureType because nothing else can be Closure other than Closure 馃槃

Or did I understand this wrong?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want you to write a test and implementation for this case :)

/**
 *
 * @template TGetDefault
 * @template TKey
 *
 * @param  TKey  $key
 * @param  TGetDefault|(callable(): TGetDefault)  $default
 * @return TKey|TGetDefault
 */

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the test cases. But the same change did not work well in CallableType. Handled a bit differently and it works now.

Also added a test case with an invokable class, seems to work as expected 馃憤馃徑

@canvural canvural force-pushed the fix-closure-type-infer-template-type branch from f27f0a3 to b981544 Compare January 13, 2022 17:13
@ondrejmirtes ondrejmirtes merged commit f1099db into phpstan:master Jan 13, 2022
@ondrejmirtes
Copy link
Member

Thank you!

@canvural canvural deleted the fix-closure-type-infer-template-type branch March 28, 2022 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants