Skip to content

Commit 32fb260

Browse files
authored
Zend: Make Closure a proper subtype of callable (#15492)
1 parent c2fddac commit 32fb260

File tree

6 files changed

+30
-0
lines changed

6 files changed

+30
-0
lines changed

UPGRADING

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ PHP 8.5 UPGRADE NOTES
6565
========================================
6666

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Closure should be covariant with callable
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public function foo(Closure $c): callable {}
8+
}
9+
class B extends A {
10+
public function foo(callable $c): Closure {}
11+
}
12+
?>
13+
OK
14+
--EXPECT--
15+
OK

Zend/zend_inheritance.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "zend_execute.h"
2424
#include "zend_inheritance.h"
2525
#include "zend_interfaces.h"
26+
#include "zend_closures.h"
2627
#include "zend_smart_str.h"
2728
#include "zend_operators.h"
2829
#include "zend_exceptions.h"
@@ -490,6 +491,19 @@ static inheritance_status zend_is_class_subtype_of_type(
490491
}
491492
}
492493

494+
/* If the parent has 'callable' as a return type, then Closure satisfies the co-variant check */
495+
if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_CALLABLE) {
496+
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
497+
if (!fe_ce) {
498+
have_unresolved = 1;
499+
} else if (fe_ce == zend_ce_closure) {
500+
track_class_dependency(fe_ce, fe_class_name);
501+
return INHERITANCE_SUCCESS;
502+
} else {
503+
return INHERITANCE_ERROR;
504+
}
505+
}
506+
493507
zend_type *single_type;
494508

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

0 commit comments

Comments
 (0)