ReflectionType for iterable / PHP 8.2

php.internals

Benjamin Morel

3 years ago
Hi internals, It just came to my attention that there is a change of behaviour between PHP 8.1 and 8.2 in the way iterable is decomposed, or not, into Traversable|array when reflected: ``` function foo(): iterable {} function bar(): stdClass|iterable {} echo (new ReflectionFunction('foo'))->getReturnType(), PHP_EOL; echo (new ReflectionFunction('bar'))->getReturnType(), PHP_EOL; ``` Output on PHP 8.1: ``` iterable stdClass|iterable ``` Output on PHP 8.2: ``` iterable stdClass|Traversable|array ``` Is this expected behaviour? Or should I file a bug? I'm particularly surprised that it behaves this way on PHP 8.2 only in the presence of union types. Thank you, Benjamin

Unnamed Person

3 years ago
On 2-11-2022 18:46, Benjamin Morel wrote:
> Hi internals, > > It just came to my attention that there is a change of behaviour between > PHP 8.1 and 8.2 in the way iterable is decomposed, or not, into > Traversable|array when reflected: > > ``` > function foo(): iterable {} > function bar(): stdClass|iterable {} > > echo (new ReflectionFunction('foo'))->getReturnType(), PHP_EOL; > echo (new ReflectionFunction('bar'))->getReturnType(), PHP_EOL; > ``` > > Output on PHP 8.1: > > ``` > iterable > stdClass|iterable > ``` > > Output on PHP 8.2: > > ``` > iterable > stdClass|Traversable|array > ``` > > Is this expected behaviour? Or should I file a bug? I'm particularly > surprised that it behaves this way on PHP 8.2 only in the presence of union > types. > > Thank you, > Benjamin >
That's a intentional behaviour change and related to this accepted PHP 8.2 RFC: https://wiki.php.net/rfc/iterator_xyz_accept_array Smile, Juliette

Claude Pache

3 years ago
> Le 2 nov. 2022 à 19:54, Juliette Reinders Folmer <php-internals_nospam@adviesenzo.nl> a écrit : > > On 2-11-2022 18:46, Benjamin Morel wrote: >> Hi internals, >> >> It just came to my attention that there is a change of behaviour between >> PHP 8.1 and 8.2 in the way iterable is decomposed, or not, into >> Traversable|array when reflected: >> >> ``` >> function foo(): iterable {} >> function bar(): stdClass|iterable {} >> >> echo (new ReflectionFunction('foo'))->getReturnType(), PHP_EOL; >> echo (new ReflectionFunction('bar'))->getReturnType(), PHP_EOL; >> ``` >> >> Output on PHP 8.1: >> >> ``` >> iterable >> stdClass|iterable >> ``` >> >> Output on PHP 8.2: >> >> ``` >> iterable >> stdClass|Traversable|array >> ``` >> >> Is this expected behaviour? Or should I file a bug? I'm particularly >> surprised that it behaves this way on PHP 8.2 only in the presence of union >> types. >> >> Thank you, >> Benjamin >> > That's a intentional behaviour change and related to this accepted PHP 8.2 RFC: https://wiki.php.net/rfc/iterator_xyz_accept_array > > Smile, > Juliette
It is rather related the following RFC: https://wiki.php.net/rfc/dnf_types The change was discussed in this thread: https://externals.io/message/117577 —Claude

Benjamin Morel

3 years ago
> > > That's a intentional behaviour change and related to this accepted PHP > 8.2 RFC: https://wiki.php.net/rfc/iterator_xyz_accept_array > > > > Smile, > > Juliette > > It is rather related the following RFC: > > https://wiki.php.net/rfc/dnf_types > > The change was discussed in this thread: > > https://externals.io/message/117577 > > —Claude
Thanks to both of you, if this change is expected then I'll adjust my code accordingly. Benjamin

Unnamed Person

3 years ago
FYI, it is also noted in the [UPGRADING][1] file:
> - Core: > . The iterable type is now a built-in compile time alias for array|Traversable. > Error messages relating to iterable will therefore now use array|Traversable. > Type Reflection is preserved for single iterable (and ?iterable) to produce > a ReflectionNamedType with name iterable, however usage of iterable in > union types will be converted to array|Traversable
[1]: https://github.com/php/php-src/blob/PHP-8.2/UPGRADING