Fix phpstan/phpstan#9844: Calling a static method over non-generic class-string results in ErrorType#5308
Conversation
|
I would not blindy this fix this looking at https://phpstan.org/r/02f65472-153c-496a-ace9-8d3747108f7d It's ErrorType for both static and non static call, which is consistent So I wonder if it's not better to report an error (in the StaticMethodCallCheck) for the static call. |
|
I think we cannot say its a undefined method.. we should say its a maybe undefined method (so the error will depend on rule-level)? but type-inference wise, I think its not correct to turn this into a ERROR in case we are not sure |
|
API Error: 529 {"type":"error","error":{"type":"overloaded_error","message":"Overloaded. https://docs.claude.com/en/api/errors"},"request_id":"req_011CZTGsTLp3w35p9Y6ix7va"} |
If you look at https://phpstan.org/r/e4c2ded1-e04e-4d7f-b439-cec1111fabf1
If we consider this as MixedType, it should be mixedType for the 3 situation IMHO. I would just say for consistency it should stay ErrorType and be reported. |
the error message this PR does not change which errors we report for your given example
I think |
ErrorType extends MixedType ; so I'm not sure of the gain to change this type into MixedType.
Yes, but maybe we should. And start reporting
Which one ? |
sounds like a independent topic to me
e.g. if you have logic which is typed on in such general purpose functions we won't/cannot get something narrower than |
95f0dc2 to
9949f00
Compare
|
|
|
Done. Applied the same fix from All tests pass (11674 tests, 0 failures) and |
|
ah nice, I think the new error in phpstan-latte is valid |
- Static method calls on non-generic class-string (e.g. $class::foo() where $class is class-string) now return mixed instead of *ERROR* - The root cause was that ClassStringType::getObjectTypeOrClassStringObjectType() returns ObjectWithoutClassType, which has hasMethod() returning maybe, causing filterTypeWithMethod() to return null - Added check in StaticCallHandler: when the resolved type is a classless object type (from class-string), return MixedType instead of ErrorType - New regression test in tests/PHPStan/Analyser/nsrt/bug-9844.php
Instance method calls ($class->foo()) on a class-string variable correctly return ErrorType since strings don't have instance methods. Only static calls ($class::foo()) should return mixed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This reverts commit 2055803.
…Type Apply the same fix from StaticCallHandler to MethodCallHandler: when methodCallReturnType returns null and the resolved type is a classless object (from plain class-string), return MixedType instead of ErrorType. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cc6b913 to
65815bd
Compare
Summary
Calling a static method on a non-generic
class-stringvariable (e.g.$class::foo()) incorrectly resulted in*ERROR*type instead ofmixed.Changes
src/Analyser/ExprHandler/StaticCallHandler.php: WhenmethodCallReturnTypereturns null and the resolved type is a classless object (from plainclass-string), returnMixedTypeinstead ofErrorTypetests/PHPStan/Analyser/nsrt/bug-9844.phpRoot cause
When resolving static method calls on dynamic class expressions,
ClassStringType::getObjectTypeOrClassStringObjectType()returnsObjectWithoutClassType. This type correctly returnsTrinaryLogic::createMaybe()forhasMethod(), butMutatingScope::filterTypeWithMethod()requiresyes(), causing it to returnnull. TheStaticCallHandlerthen defaulted toErrorType.The fix detects the case where the resolved type is a classless object type (
isObject()->yes()with no class names) — which corresponds to a plainclass-string— and returnsMixedTypeinstead ofErrorType, since any class could have any method returning any type.Test
Added
tests/PHPStan/Analyser/nsrt/bug-9844.phpwhich verifies that$class::foo()where$class: class-stringproducesmixedtype.Fixes phpstan/phpstan#9844