-
Notifications
You must be signed in to change notification settings - Fork 686
Fix binding of T of static when called from a class scope #11370
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
base: 6.x
Are you sure you want to change the base?
Conversation
I found these snippets: https://psalm.dev/r/a32e05de27<?php
abstract class Uuid
{
/**
* @template T of static
* @param T $uuid
*/
final public function equals($uuid): void {}
}
class UserId1 extends Uuid {}
class UserId2 extends Uuid {}
class User
{
public function equals(self $user): void
{
(new UserId1())->equals(new UserId2());
}
}
|
Ignore the above snippet - I pasted the wrong link. https://psalm.dev/r/a32e05de27 |
I found these snippets: https://psalm.dev/r/a32e05de27<?php
abstract class Uuid
{
/**
* @template T of static
* @param T $uuid
*/
final public function equals($uuid): void {}
}
class UserId1 extends Uuid {}
class UserId2 extends Uuid {}
class User
{
public function equals(self $user): void
{
(new UserId1())->equals(new UserId2());
}
}
|
8c1c8c3
to
d3976ce
Compare
Could you please elaborate? |
Not sure how I managed to add the same link twice https://psalm.dev/r/1028cf9de2 The major issue is resolved by this PR - I'm unure if this secondary warning is a bug or expected as I've seen it in other places but have always resolved by changing the type definitions (I can't find any other examples to hand). With this PR the error is:
In my mind |
I found these snippets: https://psalm.dev/r/1028cf9de2<?php
abstract class Uuid
{
/**
* @template T of static
* @param T $uuid
*/
final public function equals($uuid): void {}
}
class UserId1 extends Uuid {}
class UserId2 extends Uuid {}
class User
{
public function equals(self $user): void
{
(new UserId2())->equals(new UserId2());
}
}
|
Well, I am not sure either. But to me it feels that you are right, they are equal. I can also add, that it feels strange to use self instead of static, because in PHP self is about the class where code is defined and static is about the class of the object from which code is called. Self would mean that it is possible to pass any subtypes of Uuid which is undesirable. Actually, I am not sure that our use case is valid (although it had been working till the recent change). |
I found these snippets: https://psalm.dev/r/54e8166be5<?php
/**
* @template T of Uuid
*/
abstract class Uuid
{
/**
* @param T $uuid
*/
final public function equals($uuid): void {}
}
/**
* @extends Uuid<UserId1>
*/
class UserId1 extends Uuid {}
/**
* @extends Uuid<UserId2>
*/
class UserId2 extends Uuid {}
/**
* @extends Uuid<Unrelated>
*/
class SomethingElse extends Uuid {}
class Unrelated {}
class User
{
public function equals(self $user): void
{
(new UserId2())->equals(new UserId2());
}
public function failEquals(self $user): void
{
(new UserId1())->equals(new UserId2());
}
}
|
Partial fix for #11368
Issue appears to cement itself here -
psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php
Lines 418 to 421 in e052de4
as
context->self = "User"
but the method was called on an instance ofUserId
After updating to
https://psalm.dev/r/a32e05de27
becomes
Now, using self instead of static works
I've seen the "A&static, but parent type A" style messaging elsewhere and unsure if this is now a legitimate issue or not.