Skip to content

Commit

Permalink
Zend: Make Closure a proper subtype of callable
Browse files Browse the repository at this point in the history
  • Loading branch information
Girgias committed Jan 24, 2025
1 parent b2480c3 commit fec1664
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 0 deletions.
1 change: 1 addition & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ PHP 8.5 UPGRADE NOTES
========================================

- Core:
. Closure is now a proper subtype of callable
. Added support for Closures in constant expressions.
RFC: https://wiki.php.net/rfc/closures_in_const_expr

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
Closure should be covariant with callable
--FILE--
<?php

class A {
public function foo(Closure $c): callable {}
}
class B extends A {
public function foo(callable $c): Closure {}
}
?>
OK
--EXPECT--
OK
14 changes: 14 additions & 0 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "zend_execute.h"
#include "zend_inheritance.h"
#include "zend_interfaces.h"
#include "zend_closures.h"
#include "zend_smart_str.h"
#include "zend_operators.h"
#include "zend_exceptions.h"
Expand Down Expand Up @@ -490,6 +491,19 @@ static inheritance_status zend_is_class_subtype_of_type(
}
}

/* If the parent has 'callable' as a return type, then Closure satisfies the co-variant check */
if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_CALLABLE) {
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
if (!fe_ce) {
have_unresolved = 1;
} else if (fe_ce == zend_ce_closure) {
track_class_dependency(fe_ce, fe_class_name);
return INHERITANCE_SUCCESS;
} else {
return INHERITANCE_ERROR;
}
}

zend_type *single_type;

/* Traverse the list of parent types and check if the current child (FE)
Expand Down

0 comments on commit fec1664

Please sign in to comment.