-
Notifications
You must be signed in to change notification settings - Fork 509
Fixed '$this instanceof X will always be false' in traits #2045
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
Conversation
45f4b29
to
e5ebe9d
Compare
c6c3cfc
to
d052ca0
Compare
I have approached the problem from a few different angles. All worked more or less. At the end I get the feeling maybe this should be fixed at the core by e.g. treating |
d052ca0
to
d75abea
Compare
regarding the build: I can see the same errors in other PRs so I think these are unrelated |
This pull request has been marked as ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The underyling issues we need to fix is: https://phpstan.org/r/d8b183e1-7099-478e-af58-fdd5e8ab7d21
So it's not sufficient to try to if-else our way out of this problem in a single rule, we need to fix the typesystem here.
So something needs to happen to handling of Instanceof_
in TypeSpecifier.
9b059b0
to
e571a81
Compare
that was a great hint, thank you. I feel dumb for searching the solution in a lot of other phpstan components, but not the TypeSpecifier :) |
8389601
to
5e8963b
Compare
I decided this still doesn't work and we need a different approach. ThisType in a trait context needs to behave a bit differently than in a class. It needs to allow intersection with other classes, almost like an interface. |
So the bottom line is, that we need a new type? |
Some boolean arg in ThisType would suffice. But maybe TraitThisType would work too. |
f2180b4
to
9f41729
Compare
9f41729
to
e8b28a3
Compare
e8b28a3
to
9fc0b5a
Compare
9fc0b5a
to
0e92cb2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see some problems with this PR.
- TypeSpecifier shouldn't be touched. Instead, MutatingScope::enterTrait should handle ThisType.
- Any changes to isSuperTypeOf logic needs to be heavily covered by tests in TypeCombinatorTest - in dataUnion and dataIntersection.
- There are some cases the method should return
no
: a) for a final class that does not use the trait. b) For an ObjectType with a trait name c) For a type that's already subtracted in ThisType. This influences how unions and intersections are gonna end up looking like.
041c226
to
e53cd2d
Compare
|
||
$this->analyse([__DIR__ . '/../../Analyser/data/trait-instance-of.php'], [ | ||
[ | ||
'Instanceof between $this(TraitInstanceOf\ATrait1Class) and trait TraitInstanceOf\Trait2 will always evaluate to false.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for some reason this error is not reported. I get a error though, when running phpstan on this file in isolation.
otherwise I think this looks fine. I will add new TypeCombinator Tests now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's ExistingClassInInstanceOfRule rule, not ImpossibleInstanceOfRule rule.
695c257
to
79bf7ef
Compare
This pull request has been marked as ready for review. |
a2d4993
to
1c526dc
Compare
1c526dc
to
005b6f3
Compare
src/Analyser/MutatingScope.php
Outdated
$this->expressionTypes, | ||
$this->nativeExpressionTypes, | ||
array_merge($this->expressionTypes, [ | ||
'$this' => $thisHolder, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for array_merge. Simply do this before:
$expressionTypes = $this->expressionTypes;
$expressionType['$this'] = $thisHolder;
And the same thing for nativeExpressionTypes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I was inspired by another place where it was done this way. fixed both in 749fbab
|
||
$this->analyse([__DIR__ . '/../../Analyser/data/trait-instance-of.php'], [ | ||
[ | ||
'Instanceof between $this(TraitInstanceOf\ATrait1Class) and trait TraitInstanceOf\Trait2 will always evaluate to false.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's ExistingClassInInstanceOfRule rule, not ImpossibleInstanceOfRule rule.
Thank you. |
thanks for the directions. I couldn't have finished this one without your feedback <3. |
closes phpstan/phpstan#3632
test fails without the fix