Skip to content

Commit

Permalink
Fix arrow function with never return type
Browse files Browse the repository at this point in the history
Fixes GH-7900
Closes GH-9103
  • Loading branch information
iluuu1994 committed Jul 29, 2022
1 parent 2152bb2 commit f957e3e
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
4 changes: 4 additions & 0 deletions NEWS
Expand Up @@ -47,6 +47,10 @@ PHP NEWS
. Fixed bug #65069 (GlobIterator incorrect handling of open_basedir check).
(Jakub Zelenka)

- Core:
. Fixed bug GH-7900 (Arrow function with never return type compile-time
errors). (ilutov)

21 Jul 2022, PHP 8.2.0beta1

- CLI:
Expand Down
26 changes: 26 additions & 0 deletions Zend/tests/gh7900.phpt
@@ -0,0 +1,26 @@
--TEST--
GH-7900: Arrow function with never return type compile-time errors
--INI--
zend.assertions=1
assert.exception=1
--FILE--
<?php

$x = fn(): never => throw new \Exception('Here');

try {
var_dump($x());
} catch (\Exception $e) {
echo $e->getMessage(), "\n";
}

try {
assert((fn(): never => 42) && false);
} catch (\Error $e) {
echo $e->getMessage(), "\n";
}

?>
--EXPECT--
Here
assert(fn(): never => 42 && false)
7 changes: 5 additions & 2 deletions Zend/zend_ast.c
Expand Up @@ -1761,9 +1761,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
}
if (decl->child[2]) {
if (decl->kind == ZEND_AST_ARROW_FUNC) {
ZEND_ASSERT(decl->child[2]->kind == ZEND_AST_RETURN);
zend_ast *body = decl->child[2];
if (body->kind == ZEND_AST_RETURN) {
body = body->child[0];
}
smart_str_appends(str, " => ");
zend_ast_export_ex(str, decl->child[2]->child[0], 0, indent);
zend_ast_export_ex(str, body, 0, indent);
break;
}

Expand Down
13 changes: 13 additions & 0 deletions Zend/zend_compile.c
Expand Up @@ -7349,6 +7349,19 @@ static void zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel)
} else if (uses_ast) {
zend_compile_closure_uses(uses_ast);
}

if (ast->kind == ZEND_AST_ARROW_FUNC) {
bool needs_return = true;
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
zend_arg_info *return_info = CG(active_op_array)->arg_info - 1;
needs_return = !ZEND_TYPE_CONTAINS_CODE(return_info->type, IS_NEVER);
}
if (needs_return) {
stmt_ast = zend_ast_create(ZEND_AST_RETURN, stmt_ast);
decl->child[2] = stmt_ast;
}
}

zend_compile_stmt(stmt_ast);

if (is_method) {
Expand Down
3 changes: 1 addition & 2 deletions Zend/zend_language_parser.y
Expand Up @@ -1222,8 +1222,7 @@ inline_function:
| fn returns_ref backup_doc_comment '(' parameter_list ')' return_type
T_DOUBLE_ARROW backup_fn_flags backup_lex_pos expr backup_fn_flags
{ $$ = zend_ast_create_decl(ZEND_AST_ARROW_FUNC, $2 | $12, $1, $3,
zend_string_init("{closure}", sizeof("{closure}") - 1, 0), $5, NULL,
zend_ast_create(ZEND_AST_RETURN, $11), $7, NULL);
zend_string_init("{closure}", sizeof("{closure}") - 1, 0), $5, NULL, $11, $7, NULL);
((zend_ast_decl *) $$)->lex_pos = $10;
CG(extra_fn_flags) = $9; }
;
Expand Down

0 comments on commit f957e3e

Please sign in to comment.