Skip to content

Commit d84ed03

Browse files
committed
Improve error messages related to void/never return types of methods
1 parent b5a23d8 commit d84ed03

10 files changed

+68
-14
lines changed

Zend/tests/return_types/never_disallowed1.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
never return type: unacceptable cases: any return
2+
never return type: unacceptable cases: any return in a function
33
--FILE--
44
<?php
55

Zend/tests/return_types/never_disallowed2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
never return type: unacceptable cases: empty return
2+
never return type: unacceptable cases: empty return in a function
33
--FILE--
44
<?php
55

Zend/tests/return_types/never_disallowed3.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
never return type: unacceptable cases: implicit return
2+
never return type: unacceptable cases: implicit return in a function
33
--FILE--
44
<?php
55

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
never return type: unacceptable cases: empty return in a method
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function bar(): never {
8+
return;
9+
}
10+
}
11+
12+
?>
13+
--EXPECTF--
14+
Fatal error: A never-returning method must not return in %s on line %d
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
never return type: unacceptable cases: implicit return in a method
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public static function bar(): never {
8+
if (false) {
9+
throw new Exception('bad');
10+
}
11+
}
12+
}
13+
14+
try {
15+
Foo::bar();
16+
} catch (TypeError $e) {
17+
echo $e->getMessage() . "\n";
18+
}
19+
?>
20+
--EXPECT--
21+
Foo::bar(): never-returning method must not implicitly return

Zend/tests/return_types/void_disallowed1.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
void return type: unacceptable cases: explicit NULL return
2+
void return type: unacceptable cases: explicit NULL return in a function
33
--FILE--
44
<?php
55

Zend/tests/return_types/void_disallowed2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
void return type: unacceptable cases: explicit return of some other value
2+
void return type: unacceptable cases: explicit return of some other value in a function
33
--FILE--
44
<?php
55

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
void return type: unacceptable cases: explicit null return in a method
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function bar(): void {
8+
return -1; // not permitted in a void function
9+
}
10+
}
11+
12+
?>
13+
--EXPECTF--
14+
Fatal error: A void method must not return a value in %s on line %d

Zend/zend_compile.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2571,10 +2571,12 @@ static void zend_emit_return_type_check(
25712571
if (expr) {
25722572
if (expr->op_type == IS_CONST && Z_TYPE(expr->u.constant) == IS_NULL) {
25732573
zend_error_noreturn(E_COMPILE_ERROR,
2574-
"A void function must not return a value "
2575-
"(did you mean \"return;\" instead of \"return null;\"?)");
2574+
"A void %s must not return a value "
2575+
"(did you mean \"return;\" instead of \"return null;\"?)",
2576+
CG(active_class_entry) != NULL ? "method" : "function");
25762577
} else {
2577-
zend_error_noreturn(E_COMPILE_ERROR, "A void function must not return a value");
2578+
zend_error_noreturn(E_COMPILE_ERROR, "A void %s must not return a value",
2579+
CG(active_class_entry) != NULL ? "method" : "function");
25782580
}
25792581
}
25802582
/* we don't need run-time check */
@@ -2585,18 +2587,21 @@ static void zend_emit_return_type_check(
25852587
if (ZEND_TYPE_CONTAINS_CODE(type, IS_NEVER)) {
25862588
/* Implicit case handled separately using VERIFY_NEVER_TYPE opcode. */
25872589
ZEND_ASSERT(!implicit);
2588-
zend_error_noreturn(E_COMPILE_ERROR, "A never-returning function must not return");
2590+
zend_error_noreturn(E_COMPILE_ERROR, "A never-returning %s must not return",
2591+
CG(active_class_entry) != NULL ? "method" : "function");
25892592
return;
25902593
}
25912594

25922595
if (!expr && !implicit) {
25932596
if (ZEND_TYPE_ALLOW_NULL(type)) {
25942597
zend_error_noreturn(E_COMPILE_ERROR,
2595-
"A function with return type must return a value "
2596-
"(did you mean \"return null;\" instead of \"return;\"?)");
2598+
"A %s with return type must return a value "
2599+
"(did you mean \"return null;\" instead of \"return;\"?)",
2600+
CG(active_class_entry) != NULL ? "method" : "function");
25972601
} else {
25982602
zend_error_noreturn(E_COMPILE_ERROR,
2599-
"A function with return type must return a value");
2603+
"A %s with return type must return a value",
2604+
CG(active_class_entry) != NULL ? "method" : "function");
26002605
}
26012606
}
26022607

Zend/zend_execute.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,8 +1411,8 @@ ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf)
14111411
{
14121412
zend_string *func_name = get_function_or_method_name(zf);
14131413

1414-
zend_type_error("%s(): never-returning function must not implicitly return",
1415-
ZSTR_VAL(func_name));
1414+
zend_type_error("%s(): never-returning %s must not implicitly return",
1415+
ZSTR_VAL(func_name), zf->common.scope ? "method" : "function");
14161416

14171417
zend_string_release(func_name);
14181418
}

0 commit comments

Comments
 (0)