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

Problem with generics and extends #4008

Closed
nikophil opened this issue Oct 26, 2020 · 7 comments
Closed

Problem with generics and extends #4008

nikophil opened this issue Oct 26, 2020 · 7 comments
Labels
Milestone

Comments

@nikophil
Copy link

Support question

Hello,

i'm trying to solve a "contravariance problem" with generics.

I reproduced my problem in phpstan's playground: https://phpstan.org/r/74032d14-212e-4d02-9871-dc2e80ec2808

I don't understand why in the context of my object ChildGenericClass contextualized on Model, i cannot pass to its parent's constructor a generics contextualized on Model as well.

thanks for your help and amazing work :)

@ondrejmirtes
Copy link
Member

parent::__construct doesn't currently work correctly from generics point of view. There's definitely an issue about that already, but I'm gonna keep this one open too.

@ondrejmirtes ondrejmirtes added this to the Generics milestone Oct 26, 2020
@nikophil
Copy link
Author

ok perfect, thanks :)

i don't know how complicated the fix would be, but i would definitely be interested to try to help on this

@mvorisek
Copy link
Contributor

not sure if related, but the following code does not work in playground:

<?php declare(strict_types = 1);

/**
 * @template T
 */
abstract class A
{
}

/**
 * @template T
 * @extends parent<T>
 */
class B extends A
{
}

there is probably some infinity recursion, which makes even the Share button to not work (code should be shareable even if phpstan did not finish).

@nikophil
Copy link
Author

nikophil commented Dec 11, 2020

shouldn't you do this way?

<?php 

declare(strict_types = 1);

/**
 * @template T
 */
abstract class A
{
}

/**
 * @template T
 * @extends A<T>
 */
class B extends A
{
}

@mvorisek
Copy link
Contributor

mvorisek commented Dec 11, 2020

@nikophil I already did it that way, but that code is very dangerous as it can be very easily missed to be renamed when copying to another child class - thus parent<T> should work.

@phpstan-bot
Copy link
Contributor

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

@@ @@
-20: Parameter #1 $otherGenericClass of method GenericClass<BaseModel>::__construct() expects OtherGenericClass<BaseModel>, OtherGenericClass<Model> given.
+No errors

@github-actions
Copy link

github-actions bot commented May 4, 2021

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 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants