← All results

callable-object

Group: Advanced PHPDoc types · Category: ecosystem · File: phpdoc_advanced_fallback_callable_object.php

An object with __invoke(), which the engine will accept anywhere a callable is expected. A Closure qualifies without declaring the method. Analyzers that model the refinement reject an object without it; others fall back to plain object and accept it. References: - PHPStan TypeNodeResolver callable-object resolves to object&CallableType

Analyzer results

AnalyzerVersionResultDiagnostics
phan 6.0.7Phan 6.0.7 php-ast version 1.1.3 PHP version used to run Phan: 8.5.9 Enforced
phpdoc_advanced_fallback_callable_object.php:57: Argument 1 ($value) is new NotInvokable() of type \Conformance\Tests\PhpdocAdvancedFallbackCallableObject\NotInvokable but \Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject() takes callable-object defined at /Users/megurine/repo/php/php-typing-conformance/conformance/tests/phpdoc_advanced_fallback_callable_object.php:45 [PhanTypeMismatchArgument]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
phpstan 2.2.8PHPStan - PHP Static Analysis Tool 2.2.8 Enforced reported Lv.5+
phpdoc_advanced_fallback_callable_object.php:57: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject expects callable-object, Conformance\Tests\PhpdocAdvancedFallbackCallableObject\NotInvokable given. [identifier=argument.type] [reported-from-level=5]
With strict-rules
phpdoc_advanced_fallback_callable_object.php:57: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject expects callable-object, Conformance\Tests\PhpdocAdvancedFallbackCallableObject\NotInvokable given. [identifier=argument.type]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
psalm 6.16.1Psalm 6.16.1@f1f5de594dc76faf8784e02d3dc4716c91c6f6ac
next: 7.0.0-beta19
Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
mago 1.46.0mago 1.46.0 Unrecognized
phpdoc_advanced_fallback_callable_object.php:31: Cannot find class, interface, enum, or type alias `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object`. [non-existent-class-like]
phpdoc_advanced_fallback_callable_object.php:35: Invalid return type for function `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\returnsCallableObject`: expected `unknown-ref(Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object)`, but found `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\Invokable`. [invalid-return-statement]
phpdoc_advanced_fallback_callable_object.php:43: Cannot find class, interface, enum, or type alias `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object`. [non-existent-class-like]
phpdoc_advanced_fallback_callable_object.php:50: Possible argument type mismatch for argument #1 of `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsObject`: expected `object`, but possibly received `unknown-ref(Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object)`. [possibly-invalid-argument]
phpdoc_advanced_fallback_callable_object.php:53: Possible argument type mismatch for argument #1 of `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject`: expected `unknown-ref(Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object)`, but possibly received `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\Invokable`. [possibly-invalid-argument]
phpdoc_advanced_fallback_callable_object.php:54: Invalid argument type for argument #1 of `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject`: expected `unknown-ref(Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object)`, but found `(closure(): int(1))`. [invalid-argument]
phpdoc_advanced_fallback_callable_object.php:57: Possible argument type mismatch for argument #1 of `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject`: expected `unknown-ref(Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object)`, but possibly received `Conformance\Tests\PhpdocAdvancedFallbackCallableObject\NotInvokable`. [possibly-invalid-argument]
  • Recognition: spelling not resolved — reported on declaration line(s) 31, 43
  • Enforcement: 1/1 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 35: Expected valid value to be accepted, got ["Invalid return type for function `Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\returnsCallableObject`: expected `unknown-ref(Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object)`, but found `Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\Invokable`. [invalid-return-statement]"]
Line 50: Expected valid value to be accepted, got ["Possible argument type mismatch for argument #1 of `Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\acceptsObject`: expected `object`, but possibly received `unknown-ref(Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object)`. [possibly-invalid-argument]"]
Line 53: Expected valid value to be accepted, got ["Possible argument type mismatch for argument #1 of `Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\acceptsCallableObject`: expected `unknown-ref(Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object)`, but possibly received `Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\Invokable`. [possibly-invalid-argument]"]
Line 54: Expected valid value to be accepted, got ["Invalid argument type for argument #1 of `Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\acceptsCallableObject`: expected `unknown-ref(Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object)`, but found `(closure(): int(1))`. [invalid-argument]"]
mir 0.70.1mir 0.70.1 Incidental (0/1)
phpdoc_advanced_fallback_callable_object.php:54: InvalidArgument: Argument $value of acceptsCallableObject() expects 'Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object', got 'Closure(): int' [MIR0201]
  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported — incidental, since values the type admits were also rejected on line(s) 54
Expectation diff
Line 54: Expected valid value to be accepted, got ["InvalidArgument: Argument $value of acceptsCallableObject() expects 'Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object', got 'Closure(): int' [MIR0201]"]
phpantom 0.9.0phpantom_lsp 0.9.0 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
intelephense 1.18.5intelephense 1.18.5 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
phpy 0.2.0phpy 0.2.0 Unrecognized
phpdoc_advanced_fallback_callable_object.php:31: Use of unknown class: 'Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object'
phpdoc_advanced_fallback_callable_object.php:35: Return value of Conformance\Tests\PhpdocAdvancedFallbackCallableObject\returnsCallableObject() is expected to be of type Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object, Conformance\Tests\PhpdocAdvancedFallbackCallableObject\Invokable returned
phpdoc_advanced_fallback_callable_object.php:43: Use of unknown class: 'Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object'
phpdoc_advanced_fallback_callable_object.php:53: Argument '1' passed to Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject() is expected to be of type Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object, Conformance\Tests\PhpdocAdvancedFallbackCallableObject\Invokable given
phpdoc_advanced_fallback_callable_object.php:54: Argument '1' passed to Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject() is expected to be of type Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object, callable given
phpdoc_advanced_fallback_callable_object.php:57: Argument '1' passed to Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject() is expected to be of type Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object, Conformance\Tests\PhpdocAdvancedFallbackCallableObject\NotInvokable given
  • Recognition: spelling not resolved — reported on declaration line(s) 31, 43
  • Enforcement: 1/1 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 35: Expected valid value to be accepted, got ["Return value of Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\returnsCallableObject() is expected to be of type Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object, Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\Invokable returned"]
Line 53: Expected valid value to be accepted, got ["Argument '1' passed to Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\acceptsCallableObject() is expected to be of type Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object, Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\Invokable given"]
Line 54: Expected valid value to be accepted, got ["Argument '1' passed to Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\acceptsCallableObject() is expected to be of type Conformance\\Tests\\PhpdocAdvancedFallbackCallableObject\\callable-object, callable given"]
qodana 262.8665.325Qodana 262.8665.325 Unrecognized
phpdoc_advanced_fallback_callable_object.php:31: Return type in PHPDoc does not match the actual return type [PhpReturnDocTypeMismatchInspection]
phpdoc_advanced_fallback_callable_object.php:31: Undefined class 'callable-object' [PhpUndefinedClassInspection]
phpdoc_advanced_fallback_callable_object.php:35: Return value type is not compatible with declared [PhpIncompatibleReturnTypeInspection]
phpdoc_advanced_fallback_callable_object.php:43: Undefined class 'callable-object' [PhpUndefinedClassInspection]
phpdoc_advanced_fallback_callable_object.php:53: Parameter 'new Invokable()' type is not compatible with declaration [PhpParamsInspection]
phpdoc_advanced_fallback_callable_object.php:54: Parameter 'static fn (): int => 1' type is not compatible with declaration [PhpParamsInspection]
phpdoc_advanced_fallback_callable_object.php:57: Parameter 'new NotInvokable()' type is not compatible with declaration [PhpParamsInspection]
  • Recognition: spelling not resolved — reported on declaration line(s) 31, 43
  • Enforcement: 1/1 of the expected violations reported — incidental, since the spelling was not resolved
Expectation diff
Line 35: Expected valid value to be accepted, got ["Return value type is not compatible with declared [PhpIncompatibleReturnTypeInspection]"]
Line 53: Expected valid value to be accepted, got ["Parameter 'new Invokable()' type is not compatible with declaration [PhpParamsInspection]"]
Line 54: Expected valid value to be accepted, got ["Parameter 'static fn (): int => 1' type is not compatible with declaration [PhpParamsInspection]"]
noverify 0.5.5NoVerify, version 0.5.5: built on: 2025.04.22 14:36:46 OS: r-kuchinskas arm64 Commit: 4774b82f8adc53fbef38f95e97af4b953b4d1529 Unrecognized
phpdoc_advanced_fallback_callable_object.php:31: Class or interface named \Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object does not exist [undefinedClass]
phpdoc_advanced_fallback_callable_object.php:43: Class or interface named \Conformance\Tests\PhpdocAdvancedFallbackCallableObject\callable-object does not exist [undefinedClass]
  • Recognition: spelling not resolved — reported on declaration line(s) 31, 43
  • Enforcement: 0/1 of the expected violations reported — incidental, since the spelling was not resolved
steins 0.1.5steins 0.1.5 (2026-08-12 revision 39b4cc1) Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported
phpstan-strict 2.2.8PHPStan - PHP Static Analysis Tool 2.2.8 Enforced
phpdoc_advanced_fallback_callable_object.php:57: Parameter #1 $value of function Conformance\Tests\PhpdocAdvancedFallbackCallableObject\acceptsCallableObject expects callable-object, Conformance\Tests\PhpdocAdvancedFallbackCallableObject\NotInvokable given. [identifier=argument.type]
  • Recognition: spelling resolved
  • Enforcement: 1/1 of the expected violations reported
psalm-next 7.0.0-beta19Psalm 7.0.0-beta19@7e751c06a756fa64dc4c759c09fe4a173afcb433 Not enforced

No diagnostics reported.

  • Recognition: spelling resolved
  • Enforcement: 0/1 of the expected violations reported

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\PhpdocAdvancedFallbackCallableObject;

/**
 * `callable-object`
 *
 * An object with `__invoke()`, which the engine will accept anywhere a callable
 * is expected. A `Closure` qualifies without declaring the method. Analyzers
 * that model the refinement reject an object without it; others fall back to
 * plain `object` and accept it.
 *
 * References:
 * - PHPStan TypeNodeResolver `callable-object` resolves to object&CallableType
 */

final class Invokable
{
    public function __invoke(): void
    {
    }
}

final class NotInvokable
{
}

/**
 * @return callable-object
 */
function returnsCallableObject() // T: callable-object
{
    return new Invokable(); // V
}

function acceptsObject(object $value): void
{
}

/**
 * @param callable-object $value
 */
function acceptsCallableObject($value): void // T: callable-object
{
}

// A `callable-object` value always satisfies a native `object` parameter.
acceptsObject(returnsCallableObject()); // V

// An object with __invoke() satisfies the parameter, and so does a Closure.
acceptsCallableObject(new Invokable()); // V
acceptsCallableObject(static fn (): int => 1); // V

// An object without __invoke() does not.
acceptsCallableObject(new NotInvokable()); // E?: an object without __invoke() is not a callable-object