From e8a33a8ec61325eb65297c265c2c94c8fc229457 Mon Sep 17 00:00:00 2001 From: phpstan-bot <79867460+phpstan-bot@users.noreply.github.com> Date: Mon, 16 Feb 2026 23:40:51 +0000 Subject: [PATCH 1/2] Fix static method call on non-generic class-string returning ErrorType - When calling a static method on a non-generic class-string (e.g. $class::foo() where $class is class-string), the result was ErrorType instead of MixedType - Root cause: class-string converts to ObjectWithoutClassType via getObjectTypeOrClassStringObjectType(), which returns maybe for hasMethod(), causing filterTypeWithMethod() to reject it and methodCallReturnType() to return null, falling back to ErrorType - Fix checks if the static call is on an expression (not a class name), the resolved type has no known class names, and hasMethod is not definitively no, returning MixedType in that case - New regression test in tests/PHPStan/Analyser/nsrt/bug-9844.php Closes https://github.com/phpstan/phpstan/issues/9844 --- src/Analyser/MutatingScope.php | 10 +++++++++- tests/PHPStan/Analyser/nsrt/bug-9844.php | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Analyser/nsrt/bug-9844.php diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index db31ce7669..fd1bf9257f 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -6390,7 +6390,15 @@ private function getStaticCallType(Expr\StaticCall $node): ?Type $node, ); if ($callType === null) { - $callType = new ErrorType(); + if ( + !$node->class instanceof Name + && count($staticMethodCalledOnType->getObjectClassNames()) === 0 + && !$staticMethodCalledOnType->hasMethod($node->name->toString())->no() + ) { + $callType = new MixedType(); + } else { + $callType = new ErrorType(); + } } if ($node->class instanceof Expr) { diff --git a/tests/PHPStan/Analyser/nsrt/bug-9844.php b/tests/PHPStan/Analyser/nsrt/bug-9844.php new file mode 100644 index 0000000000..a6ec9c098d --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-9844.php @@ -0,0 +1,17 @@ + Date: Tue, 17 Feb 2026 00:14:59 +0000 Subject: [PATCH 2/2] Fix CI failures [claude-ci-fix] Automated fix attempt 1 for CI failures. --- src/Analyser/MutatingScope.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index fd1bf9257f..b5e7ee2c71 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -6390,14 +6390,13 @@ private function getStaticCallType(Expr\StaticCall $node): ?Type $node, ); if ($callType === null) { + $callType = new ErrorType(); if ( !$node->class instanceof Name && count($staticMethodCalledOnType->getObjectClassNames()) === 0 - && !$staticMethodCalledOnType->hasMethod($node->name->toString())->no() + && $staticMethodCalledOnType->hasMethod($node->name->toString()) !== TrinaryLogic::createNo() ) { $callType = new MixedType(); - } else { - $callType = new ErrorType(); } }