Hi Aleksander

> I see it's a subtype, I don't get why. Wouldn't it be better to be a
> separate type so return type covariance is not allowed (as it is with
> void)? Was it a design decision or a side product of the implementation?

This is a fairly common technique. For example, this is from the
TypeScript handbook:

https://www.typescriptlang.org/docs/handbook/basic-types.html#never

> The never type is a subtype of, and assignable to, every type; however, no 
> type is a subtype of, or assignable to, never (except never itself). Even any 
> isn’t assignable to never.

Imagine the following scenario:

function foo(callable(): int $computeSomething) {
    $magicNumber = $computeSomething();
}

function bar(): noreturn {
    throw new Exception('bar');
}

// Is completely type-safe as $magicNumber will never be assigned
foo('bar');

// Without noreturn being a bottom type you'd have to do this
foo(function(): int {
    bar();
});

We don't have callable types yet but it's common in other languages.
The point is that, since noreturn will throw, terminate or never end,
$magicNumber will never be assigned. This means effectively the return
type of any function can be safely substituted with noreturn.

The other benefit is that you can accurately typehint an overridden method.

class Foo {
    function baz(): int {
        return 42;
    }
}

class Bar extends Foo {
    function baz(): noreturn {
        throw new Exception();
    }
}

$bar = new Bar();
$bar->baz(); // IDE will know this always terminates
qux(); // Dead code

Not every language allows this but it does make sense semantically.
It's not a deal breaker if we don't have it but given that the
implementation is fairly simple I don't see why we wouldn't.

Ilija

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to