diff --git a/src/Type/Constant/ConstantArrayType.php b/src/Type/Constant/ConstantArrayType.php index 599e5a026a..6cff7ef3af 100644 --- a/src/Type/Constant/ConstantArrayType.php +++ b/src/Type/Constant/ConstantArrayType.php @@ -564,9 +564,15 @@ public function findTypeAndMethodNames(): array $has->yes() && !$phpVersion->supportsCallableInstanceMethods() ) { - $methodReflection = $type->getMethod($methodName->getValue(), new OutOfClassScope()); - if ($classOrObject->isString()->yes() && !$methodReflection->isStatic()) { - continue; + $isString = $classOrObject->isString(); + if ($isString->yes()) { + $methodReflection = $type->getMethod($methodName->getValue(), new OutOfClassScope()); + + if (!$methodReflection->isStatic()) { + continue; + } + } elseif ($isString->maybe()) { + $has = $has->and(TrinaryLogic::createMaybe()); } } diff --git a/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php b/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php index 6c71a1a7c0..bd8ad74e49 100644 --- a/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php @@ -353,4 +353,17 @@ public function testPipeOperator(): void ]); } + public function testMaybeNotCallable(): void + { + $errors = []; + if (PHP_VERSION_ID >= 80000) { + $errors[] = [ + "Trying to invoke array{'MaybeNotCallable\\\Bar'|\$this(MaybeNotCallable\Bar), 'doFoo'} but it might not be a callable.", + 15, + ]; + } + + $this->analyse([__DIR__ . '/data/maybe-not-callable.php'], $errors); + } + } diff --git a/tests/PHPStan/Rules/Functions/data/maybe-not-callable.php b/tests/PHPStan/Rules/Functions/data/maybe-not-callable.php new file mode 100644 index 0000000000..47bed964c4 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/maybe-not-callable.php @@ -0,0 +1,17 @@ +