]> granicus.if.org Git - php/commitdiff
Allow generators to have a real return type of `mixed` or `object`
authorTyson Andre <tysonandre775@hotmail.com>
Mon, 25 May 2020 20:38:08 +0000 (16:38 -0400)
committerTyson Andre <tysonandre775@hotmail.com>
Tue, 26 May 2020 13:57:10 +0000 (09:57 -0400)
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`

Closes GH-5626

Zend/tests/return_types/generators001.phpt
Zend/tests/return_types/generators002.phpt
Zend/tests/return_types/generators006.phpt [new file with mode: 0644]
Zend/zend_compile.c

index 9f89d71102f6e74685ea4300fa454cc87f624a87..4cff100a8f1634b15f5c0bb27ce6e369d16006d1 100644 (file)
@@ -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) {
+}
index 2e42f4b052880a9ab4d4707b7b0abd9b9312b0f7..d5ef4f2d48d76bac705b773d0ac07f6aef9a3106 100644 (file)
@@ -1,9 +1,9 @@
 --TEST--
-Generator return type must be Generator, Iterator or Traversable
+Generator return type must be a supertype of Generator
 --FILE--
 <?php
 function test1() : StdClass {
     yield 1;
 }
 --EXPECTF--
-Fatal error: Generators may only declare a return type containing Generator, Iterator, Traversable, or iterable, StdClass is not permitted in %s on line %d
+Fatal error: Generator return type must be a supertype of Generator, StdClass given in %s on line %d
diff --git a/Zend/tests/return_types/generators006.phpt b/Zend/tests/return_types/generators006.phpt
new file mode 100644 (file)
index 0000000..00dbc9e
--- /dev/null
@@ -0,0 +1,9 @@
+--TEST--
+Generator return type must be a supertype of Generator (with union types)
+--FILE--
+<?php
+function test1() : StdClass|ArrayObject|array {
+    yield 1;
+}
+--EXPECTF--
+Fatal error: Generator return type must be a supertype of Generator, StdClass|ArrayObject|array given in %s on line %d
index 7638bd16fc5ebaae359e661c46bdbdbb358ad2b4..9cfe8be1ecb6da4fc4fb31ca922fedade788a191 100644 (file)
@@ -1263,7 +1263,7 @@ static void zend_mark_function_as_generator() /* {{{ */
 
        if (CG(active_op_array)->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));
                }
        }