From f93b17076a25e2a06af50a6d177ae4badc5e44c3 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 9 Mar 2026 21:57:50 +0000 Subject: [PATCH] Zend: inherit interfaces early (#18622) The primary motivation for this is that this is required for my abstract generic types proof of concept, as the resolving of bound types needs to happen early to properly track the types. However, there doesn't seem to be a good reason for delaying the inheritance of interfaces. This approach might even allow us to drop the `iface` parameter of the `interface_gets_implemented()` handler as the interface name is always known. --- .../enum/no-class-implements-backed-enum.phpt | 2 +- ...y_interfaces_error_via_indirect_interface.phpt | 15 +++++++++++++++ Zend/zend_inheritance.c | 7 ++++--- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 Zend/tests/inheritance/enum_only_interfaces_error_via_indirect_interface.phpt diff --git a/Zend/tests/enum/no-class-implements-backed-enum.phpt b/Zend/tests/enum/no-class-implements-backed-enum.phpt index f6f37818da5..f8d4fd13a42 100644 --- a/Zend/tests/enum/no-class-implements-backed-enum.phpt +++ b/Zend/tests/enum/no-class-implements-backed-enum.phpt @@ -7,4 +7,4 @@ class Foo implements BackedEnum {} ?> --EXPECTF-- -Fatal error: Non-enum class Foo cannot implement interface BackedEnum in %s on line %d +Fatal error: Non-enum class Foo cannot implement interface UnitEnum in %s on line %d diff --git a/Zend/tests/inheritance/enum_only_interfaces_error_via_indirect_interface.phpt b/Zend/tests/inheritance/enum_only_interfaces_error_via_indirect_interface.phpt new file mode 100644 index 00000000000..66a92153205 --- /dev/null +++ b/Zend/tests/inheritance/enum_only_interfaces_error_via_indirect_interface.phpt @@ -0,0 +1,15 @@ +--TEST-- +Interface that is extended from Enum only interface shouldn't be implementable by non-enum class +--FILE-- + +--EXPECTF-- +Fatal error: Non-enum class C cannot implement interface UnitEnum in %s on line %d diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index b5fc262ec1e..ba13a3233ed 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2168,6 +2168,10 @@ static void do_interface_implementation(zend_class_entry *ce, zend_class_entry * zend_class_constant *c; uint32_t flags = ZEND_INHERITANCE_CHECK_PROTO | ZEND_INHERITANCE_CHECK_VISIBILITY; + if (iface->num_interfaces) { + zend_do_inherit_interfaces(ce, iface); + } + if (!(ce->ce_flags & ZEND_ACC_INTERFACE)) { /* We are not setting the prototype of overridden interface methods because of abstract * constructors. See Zend/tests/interface_constructor_prototype_001.phpt. */ @@ -2199,9 +2203,6 @@ static void do_interface_implementation(zend_class_entry *ce, zend_class_entry * } ZEND_HASH_FOREACH_END(); do_implement_interface(ce, iface); - if (iface->num_interfaces) { - zend_do_inherit_interfaces(ce, iface); - } } /* }}} */