Repository navigation
Fix false positive dead catch on property assignment - #1047
Conversation
|
Rerunning tests because the failing tests seemed not related to this PR. |
|
@ondrejmirtes |
| $scope = $scope->assignExpression($var, $assignedExprType); | ||
| } | ||
| if ($assignedExprType->isSuperTypeOf($propertyReflection->getWritableType())->no()) { | ||
| $throwPoints[] = ThrowPoint::createImplicit($scope, $assignedExpr); |
There was a problem hiding this comment.
The error might occur if we have a property with a native type int and we try to assign int|string into it. It means that the condition should be !$assignedExprType->isSuperTypeOf($propertyReflection->getWritableType())->yes() instead. Please add a test and modify the implementation.
Also there might be a situation where the property is not defined at all. In that case we should simulate MethodCall to __set and see what throw points that produces (when the method exists). You can do that by calling $this->processExprNode(new MethodCall($var->var, '__set'), $scope, static function (): void {}, $context)->getThrowPoints().
There's a similar bug that you can look to in the next PR :) phpstan/phpstan#4852
Thank you!
|
@ondrejmirtes |
|
@ondrejmirtes
ThrowPoint::createExplicit($scope, $scope->getType(new New_(new Name(\TypeError::class))), $assignedExpr, false) |
|
Instead of Explicit/implicit throw points - "explicit" is for cases where the So I guess in this case it's an explicit throw point. |
|
Thank you very much for your information!
phpstan-src/src/Type/ObjectType.php Line 61 in d32942a Thanks, I had a misunderstanding watching property $superTypes here. I was thinking that calling new ObjectType(\TypeError::class) is not setting the $superTypes, but this property was only a cache.
|
| $scope = $scope->assignExpression($var, $assignedExprType); | ||
| // simulate dynamic property assign to get throw points | ||
| $throwPoints = array_merge($throwPoints, $this->processExprNode( | ||
| new MethodCall($var->var, '__set'), |
There was a problem hiding this comment.
This needs some tests :)
- Class without the
__setmagic method - does not throw anything (dead catch reported). - Class with
__setmagic method and@throws voidannotation (dead catch reported). - Class with
__setmagic method and@throws SomeException(dead catch not reported).
There was a problem hiding this comment.
👍
For the first case, there is a implicit ThrowPoint already, when method reflection is not found.
I'm not sure with the purpose of this throw point, so I'm gonna check it.
phpstan-src/src/Analyser/NodeScopeResolver.php
Line 1994 in 2167438
There was a problem hiding this comment.
Ok, understood
I shouldn’t process __set if its not declared.
|
Thank you! |
fixes phpstan/phpstan#6256
I hope I understood the concept of ThrowPoint correctly...