[php-src] Issue #20728: `never` union type
[email protected] (kkmuffme)
| Newsgroups | php.bugs |
|---|---|
| Message-ID | <4TCwpgm0Vy35LBKJo5ofMqc8w1qT3nsMRehbULMKyHk@main.internal.php.net> |
Issue: https://github.com/php/php-src/issues/20728
Author: kkmuffme
### Description
```php
function foo(): bool|never {
if (rand(0,1)) {
echo "false";
return false;
}
echo "exit";
exit;
}
foo();
```
https://www.php.net/manual/en/language.types.never.php
>[never](https://www.php.net/manual/en/language.types.never.php) is a return-only type indicating the function does not terminate
>it cannot be part of a [union type](https://www.php.net/manual/en/language.types.type-system.php#language.types.type-system.composite.union) declaration
What if a function only terminates conditionally like in the example above? Currently using "bool" type hint works above, however that loses relevant information, which currently can only be conveyed with a phpdoc comment.
The docs state:
>**Therefore**, it cannot be part of a union type
but there is nothing "therefore" about it and no reason why it cannot be part of a union type
(except PHP itself "enforcing" no union types of overlapping built-in types - but if we look at the int/float behavior of allowing int, this isn't strictly true anyway, and not true at all when taking non-built in types into account, e.g. with child/parent classes)
This has been working in static analysis (psalm, phpstorm) since ages too and I think is somthing that should be natively supported too.
(I'm the one who implemented this in psalm back then)