Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for never type #337

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

added support for never type #337

wants to merge 2 commits into from

Conversation

i582
Copy link
Contributor

@i582 i582 commented Oct 15, 2021

RFC: https://wiki.php.net/rfc/noreturn_type

The never type is used as the return type of a function that always throws
exceptions or interrupts the flow of execution with exit/die.

function redirect(string $uri): never {
    header('Location: ' . $uri);
    exit();
}

never vs @kphp-no-return

KPHP has the @kphp-no-return annotation, which indicates that a function
always interrupts the flow of execution with exit/die.

/**
 * @kphp-no-return
 */
function redirect(string $uri) {
    header('Location: ' . $uri);
    exit();
}

At the same time, exceptions cannot be thrown from the function with this annotation,
unlike functions returning never in PHP 8.

In our codebase we don't use the @kphp-no-return tag, the only place where
it is used is in functions.txt, where we mark the exit/die functions.

So the new type never is less strict, but in general looks like a complete replacement
for the annotation, which can be removed as unnecessary. With new type, exit/die
functions will return never.

Since @kphp-no-return affects the construction of the CFG (Control flow graph),
which occurs before the type inference, in order for the new behavior to remain the
same, we establish that the presence of an explicit type hint never or @return never
is equivalent to adding the @kphp-no-return annotation.

Thus, the new functions with never typehint will be taken into account when building
the CFG, and the old ones (even if they always interrupt the flow of execution) also will not.

Code gen

Previously, functions marked with the @kphp-no-return annotation generated functions with
__attribute__((noreturn)), but since functions can now also throw exceptions, the function
cannot be marked with this attribute, because in case of exceptions we implicitly return null
(due to specifics of the implementation of exceptions).

Compile-time errors

When using annotations, checking that something is explicitly or implicitly returned from
a function happened in FinalCheckPass, now, since never is a new type, such errors
are checked by existing type checks and there is no need to add new additional checks.

never can only be used in type hints for the return type of a function, therefore, we
added checks for its use for parameters and for class properties.
This check was lost for void, so a check was added for this type as well.

@i582 i582 added the PHP8 PHP8 feature label Oct 15, 2021
@i582 i582 changed the title WIP: added support for never type added support for never type Oct 17, 2021
@Tsygankov-Slava Tsygankov-Slava mentioned this pull request Jul 3, 2023
44 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PHP8 PHP8 feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant