From e0ee8b2d3b8376ab4bd157b13dcbe1785667d94f Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Mon, 25 May 2020 16:38:08 -0400 Subject: [PATCH] Allow generators to have a real return type of `mixed` or `object` Fixes an edge case overlooked in https://github.com/php/php-src/pull/5313 Generators are objects, so `object` should have also been allowed in addition to `iterable` and `Traversable` --- Zend/tests/return_types/generators001.phpt | 23 +++++++++++++++++++++- Zend/tests/return_types/generators002.phpt | 4 ++-- Zend/tests/return_types/generators006.phpt | 9 +++++++++ Zend/zend_compile.c | 5 ++--- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 Zend/tests/return_types/generators006.phpt diff --git a/Zend/tests/return_types/generators001.phpt b/Zend/tests/return_types/generators001.phpt index 9f89d71102f6e..4cff100a8f163 100644 --- a/Zend/tests/return_types/generators001.phpt +++ b/Zend/tests/return_types/generators001.phpt @@ -14,10 +14,25 @@ function test3() : Traversable { yield 3; } +function test4() : mixed { + yield 4; +} + +function test5() : object { + yield 5; +} + +function test6() : object|callable { + yield 6; +} + var_dump( test1(), test2(), - test3() + test3(), + test4(), + test5(), + test6(), ); --EXPECTF-- object(Generator)#%d (%d) { @@ -26,3 +41,9 @@ object(Generator)#%d (%d) { } object(Generator)#%d (%d) { } +object(Generator)#%d (%d) { +} +object(Generator)#%d (%d) { +} +object(Generator)#%d (%d) { +} diff --git a/Zend/tests/return_types/generators002.phpt b/Zend/tests/return_types/generators002.phpt index 2e42f4b052880..d5ef4f2d48d76 100644 --- a/Zend/tests/return_types/generators002.phpt +++ b/Zend/tests/return_types/generators002.phpt @@ -1,9 +1,9 @@ --TEST-- -Generator return type must be Generator, Iterator or Traversable +Generator return type must be a supertype of Generator --FILE-- fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { zend_type return_type = CG(active_op_array)->arg_info[-1].type; - zend_bool valid_type = (ZEND_TYPE_FULL_MASK(return_type) & MAY_BE_ITERABLE) != 0; + zend_bool valid_type = (ZEND_TYPE_FULL_MASK(return_type) & (MAY_BE_ITERABLE | MAY_BE_OBJECT)) != 0; if (!valid_type) { zend_type *single_type; ZEND_TYPE_FOREACH(return_type, single_type) { @@ -1278,8 +1278,7 @@ static void zend_mark_function_as_generator() /* {{{ */ if (!valid_type) { zend_string *str = zend_type_to_string(return_type); zend_error_noreturn(E_COMPILE_ERROR, - "Generators may only declare a return type containing " \ - "Generator, Iterator, Traversable, or iterable, %s is not permitted", + "Generator return type must be a supertype of Generator, %s given", ZSTR_VAL(str)); } }