Changes in new versions / PHP 8.1

// *** before: ***
function fail($message) {
    // the docblock is the only hint that this never returns normally
    throw new RuntimeException($message);
}

// *** in version 8.1: ***
function fail(string $message): never {
    throw new RuntimeException($message);
}

function process(?User $user) {
    if ($user === null) {
        fail('user is required');
    }
    // the engine knows execution never reaches this point otherwise
    return $user->getName();
}