-
Notifications
You must be signed in to change notification settings - Fork 659
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
Intersection types with built-in classes does not work #7520
Comments
I found these snippets: https://psalm.dev/r/07aeb2b8c9<?php
class Foo {}
class Bar
{
private Foo&\DateTime $date;
}
|
It shouldn't crash like that, but intersecting two classes doesn't make much sense anyway. Either we already know one class extends the other, or we know they can't possibly intersect. It seems to work correctly for interfaces: https://psalm.dev/r/1b136de642. Here's a better example that shouldn't break: https://psalm.dev/r/08a3bb46d9. |
I found these snippets: https://psalm.dev/r/1b136de642<?php
class Foo {}
class Bar
{
private Foo&\DateTimeInterface $date;
}
https://psalm.dev/r/08a3bb46d9<?php
interface Foo {}
class Bar
{
private Foo&\DateTime $date;
}
|
My real use-case is intersecting an interface and |
I found these snippets: https://psalm.dev/r/f544acf7cc<?php
class Foo {}
class Bar
{
private \SessionHandlerInterface&Foo $date;
}
|
(it still breaks if you make |
The order of the type seems to matter. For example, this works, but this does not. |
I found these snippets: https://psalm.dev/r/09f17deb82<?php
interface FooInterface {}
class Works
{
public function __construct(private FooInterface&\SessionHandlerInterface $foo){}
}
https://psalm.dev/r/e9af3116a7<?php
interface FooInterface {}
class Works
{
public function __construct(private \SessionHandlerInterface&FooInterface $foo){}
}
|
ouch, this breaks badly. I'll look into it. I'm not sure what will happen by intersecting a mock object and an interface though... Either the mock object already implement the interface and it should already work or it doesn't and it's weird |
Intersecting objects and interfaces makes sense when the class is non-final, since children can implement interfaces. |
Fwiw PHPUnit returns an intersection type when creating a mock |
Thanks for feedback :) So far, I found out that the issue happens because of Psalm didn't manage to scan SessionHandlerInterface before it tries to create the intersectionType (for that, Psalm needs to know the class storage). I'm still digging |
@orklah Given that docblock types work I'd take a look at the PR that added support for intersection signature types, maybe there's something happening during scanning that needs to happen during analysis? |
I found these snippets: https://psalm.dev/r/39c247533a<?php
class Foo {}
class Bar
{
/** @var Foo&\DateTime */
private $date;
}
|
That's highly possible, but I'm confused by the fact it works when you flip the intersection around. If I solve the mystery here and the answer is not right, I'll try to fix it further |
Probably related: #8387, I think we need to move some of the intersection stuff to the analysis phase instead of the scanning phase, but I'm not sure how much work that'll be. |
Hey here is another example. Its not possible to scan a symfony project right now.
|
I just stumbled upon this problem myself. It would be great if the psalm team fixes this. |
https://psalm.dev/r/07aeb2b8c9
The text was updated successfully, but these errors were encountered: