[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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.