diff options
author | Nikita Popov <nikic@php.net> | 2015-03-22 18:50:36 +0100 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2015-03-22 18:56:14 +0100 |
commit | a34f81deee53ddf3b59405fc37d9f92cf41c8636 (patch) | |
tree | 2cffb4a85a3644aacc1e2b4c01a6c853a550c17a | |
parent | a50e9d87f265f911f9c76ca0e998588be0bd6eac (diff) | |
download | php-git-a34f81deee53ddf3b59405fc37d9f92cf41c8636.tar.gz |
Allow adding return type during inheritance
This is allowed as per the return types RFC. The test for this
behavior happened to use an internal class without arginfo, which
is why this was not properly implemented.
-rw-r--r-- | Zend/tests/typehints/add_return_type.phpt | 23 | ||||
-rw-r--r-- | Zend/zend_inheritance.c | 9 |
2 files changed, 29 insertions, 3 deletions
diff --git a/Zend/tests/typehints/add_return_type.phpt b/Zend/tests/typehints/add_return_type.phpt new file mode 100644 index 0000000000..de8a17d8c0 --- /dev/null +++ b/Zend/tests/typehints/add_return_type.phpt @@ -0,0 +1,23 @@ +--TEST-- +Adding a return type during inheritance is allowed +--FILE-- +<?php + +interface One { + public function a(); + public function b(); + public function c(); + public function d(); +} + +interface Two extends One { + public function a() : stdClass; + public function c() : callable; + public function b() : array; + public function d() : int; +} + +?> +Done +--EXPECT-- +Done diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index e3ef17cc90..3e9083c8a4 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -328,11 +328,14 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c } } - /* check return type compataibility */ - if ((proto->common.fn_flags | fe->common.fn_flags) & ZEND_ACC_HAS_RETURN_TYPE) { - if ((proto->common.fn_flags ^ fe->common.fn_flags) & ZEND_ACC_HAS_RETURN_TYPE) { + /* Check return type compatibility, but only if the prototype already specifies + * a return type. Adding a new return type is always valid. */ + if (proto->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { + /* Removing a return type is not valid. */ + if (!(fe->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) { return 0; } + if (!zend_do_perform_type_hint_check(fe, fe->common.arg_info - 1, proto, proto->common.arg_info - 1)) { return 0; } |