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
Lower bounds support #5179
Comments
@jost125 After the latest commit in dev-master, PHPStan now reports different result with your code snippet: @@ @@
-No errors
+58: Parameter #2 $b of method Monoid<B>::concat() expects B, A given. Full report
|
@jost125 After the latest commit in dev-master, PHPStan now reports different result with your code snippet: @@ @@
-No errors
+-1: Internal error: PHPStan\Rules\Methods\WrongCaseOfInheritedMethodRule::findMethod(): Argument #2 ($classReflection) must be of type PHPStan\Reflection\ClassReflection, null given, called in /var/task/vendor/phpstan/phpstan-strict-rules/src/Rules/Methods/WrongCaseOfInheritedMethodRule.php on line 40
+Run PHPStan with --debug option and post the stack trace to:
+https://github.com/phpstan/phpstan/issues/new?template=Bug_report.md Full report
|
This would be really useful |
@ondrejmirtes any news about this issue? |
This sounds a lot like There's an open WIP PR for that: phpstan/phpstan-src#1492 There's also some work underway for call-site variance which is gonna be cool too: phpstan/phpdoc-parser#138 |
Template variance and bounds are different things, but they are loosely related. You indeed need to support both type of bounds (upper and lower) to allow some patterns in combination of template variances. In my case I would like to have covariant collection, which support immutable additions (which means use template type in contravariant position). Which you cannot do off course. But what you CAN do is to introduce new invariant type lower bounded by original type, which bypasses it. (Thats how scala does it in standard library https://www.scala-lang.org/api/2.13.3/scala/collection/immutable/List.html#::[B%3E:A](elem:B):List[B] ) The #3960 indeed looks similar. It is slightly different case, but if the author could use lower bound, he would be able to specify type for his use case. The term "Contravariant bound" is I believe incorrect (I have never heard it called this way, probably author just meant lower bound). BTW I tought that template-contravariant is already supported to some extent, not? As of call-site variance. Projections are really nice, if implemented, I will be really happy. They are slightly different things from bounds though. |
These examples are really mind-bending for me :) For example, I only understood type projections after Jiří Pudil explained it to me in person. Because before PHPStan, I never truly worked with generics and have no experience with them from other languages, I learnt them along the way, and I have no concept or need for these advanced features :) I'm not sure how to implement it currently though. Each bound type (like |
I was considering sending PR into phpstan myself, but to be honest, phpstan is quite complex project and there is quite high barrier. Is there some kind of "internal documentation" or some kind of "concepts" described somewhere publicly? |
You could start here https://phpstan.org/developing-extensions/core-concepts - writing extensions gives you a good idea how the internals work. This article is especially relevant for you https://phpstan.org/developing-extensions/type-system. The hardest part is to figure out what But as I said - I'm not sure myself how to approach this - if we should create classes like |
I already read those. I have even developed some minor extensions for our need. If there is no other material I will try to dig more in source code itself. As a super quick check, top of the mind, I think it should be part of iterface here: https://apiref.phpstan.org/1.8.x/PHPStan.Type.Generic.TemplateType.html It already has method
Client code (usage of BTW: there are some other design choices.
I will check the source code and revisit this issue more. Edit: |
I like your thinking about this. A new method should really be used for this so that the usage is fool-proof. If we only add We should force users to start using a new method so that they check bound + direction simultaneously. And the old one should be deprecated. But I don't know if Maybe something like Feel free to start with a PR to phpstan/phpdoc-parser - it'd be a good starting point to also have discussion with Psalm maintainters to see if they're interested in this, and to agree upon a syntax. |
I'll throw in my two cents to revive the discussion: I wouldn't mind having both This would force code to always take both bounds into account, without the need for special-casing each direction. Most importantly, it would be forward-compatible and allow PHPStan to rollout the support gradually: if we later found consensus on the syntax and chose to support specifying both bounds in the userland, it would just create explicit bounds [U, L], and an exact bound E could simply be translated into [E, E]. |
Support of lower bounds for generics / templates
Hi, first of all, thanks for all the great work, that has been done on generics lately.
To have generics more complete I suggest to introduce lower bounds, since phpstan already have a way to define upper bounds.
Lower bound behaves similarly to upper bound, only difference is, that it allows types in opposite direction (super types instead of sub types).
I propose syntax
@template B super A
with meaningB
must be same type asA
or super type ofA
.Here is example, that I would like to support with phpstan:
https://phpstan.org/r/3fb61a92-b113-4d99-851c-25e406ea05cc
I am not good in making simplistic examples, so if anyone has better (simpler) example to show, please add it here.
Lower bounds are supported in other languages, which supports generics, e.g.:
super
keyword)Here is BTW link to our library, where we would use it https://github.com/bonami/collections e.g. here bonami/collections@a0bd909#diff-5d09c8cea366687b9742aed7f42996c7d73643bc15c4cae25f21e474c7881341R712 (we cannot define ArrayList template as covariant because of this limitation, which has other impacts)
The text was updated successfully, but these errors were encountered: