Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

in return type class with __invoke method is not a callable #18161

Open
Lumaraf opened this issue Mar 27, 2025 · 3 comments
Open

in return type class with __invoke method is not a callable #18161

Lumaraf opened this issue Mar 27, 2025 · 3 comments

Comments

@Lumaraf
Copy link

Lumaraf commented Mar 27, 2025

Description

The following code:

<?php
interface I {
    public function test(): callable;
}
class Invokable {
    public function __invoke() {}
}
var_dump(is_callable(new Invokable()));
class C implements I {
    public function test(): Invokable {}
}

Resulted in this output:

bool(true)

Fatal error: Declaration of C::test(): Invokable must be compatible with I::test(): callable in /in/PfBWX on line 10

Process exited with code 255.

Methods should be able to restrict callable return types from interfaces and parent classes to more specific types that unconditionally fall within the callable type. Any class or interface that contains an __invoke method should be considered a callable type an be allowed as a more specific subtype of callable in subclasses. Also \Closure should be allowed as well.

PHP Version

8.4.5

Operating System

No response

@Girgias
Copy link
Member

Girgias commented Mar 27, 2025

Closure being covariant to callable is fixed on master, see: #15492

But the only way for what you want to be true is that Invokable is an engine interface, which requires an RFC.

@iluuu1994
Copy link
Member

I suppose we could do some duck typing here, and check for zend_hash_find_known_hash(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE)), or preferably store it in ce->__invoke like we do the other magic methods. But an interface analogous to Stringable would surely be cleaner.

@Girgias
Copy link
Member

Girgias commented Mar 28, 2025

I really don't want to open the duck typing can of worms. I think adding such an interface shouldn't be that controversial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants