From a6484d9fd8adcba9fd4d9e7d3e614bc1b44af8c3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 18 May 2021 14:21:23 +0200 Subject: [PATCH 1/2] Allow named args after unpack --- .../named_params/unpack_and_named_1.phpt | 50 +++++++++++++++++-- .../named_params/unpack_and_named_2.phpt | 4 +- Zend/zend_compile.c | 9 +--- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/Zend/tests/named_params/unpack_and_named_1.phpt b/Zend/tests/named_params/unpack_and_named_1.phpt index 24d448dc8bbc0..23bb679c08f75 100644 --- a/Zend/tests/named_params/unpack_and_named_1.phpt +++ b/Zend/tests/named_params/unpack_and_named_1.phpt @@ -1,10 +1,52 @@ --TEST-- -Mixing unpacking and named params (1) +Named args after unpacking (supported) --FILE-- 2], b: 3); + +function test2($a, $b, $c = 3, $d = 4) { + var_dump($a, $b, $c, $d); +} + +test2(...[1, 2], d: 40); +test2(...['b' => 2, 'a' => 1], d: 40); + +try { + test2(...[1, 2], b: 20); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} ?> ---EXPECTF-- -Fatal error: Cannot combine named arguments and argument unpacking in %s on line %d +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + ["a"]=> + int(3) +} +array(3) { + [0]=> + int(1) + ["a"]=> + int(2) + ["b"]=> + int(3) +} +int(1) +int(2) +int(3) +int(40) +int(1) +int(2) +int(3) +int(40) +Named parameter $b overwrites previous argument diff --git a/Zend/tests/named_params/unpack_and_named_2.phpt b/Zend/tests/named_params/unpack_and_named_2.phpt index 2035b2e2dde6f..772000d1ad26f 100644 --- a/Zend/tests/named_params/unpack_and_named_2.phpt +++ b/Zend/tests/named_params/unpack_and_named_2.phpt @@ -1,5 +1,5 @@ --TEST-- -Mixing unpacking and named params (2) +Named args before unpacking (not supported) --FILE-- --EXPECTF-- -Fatal error: Cannot combine named arguments and argument unpacking in %s on line %d +Fatal error: Cannot use argument unpacking after named arguments in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 07e8679885163..22ba3b5d05b6f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3472,7 +3472,7 @@ uint32_t zend_compile_args( if (arg->kind == ZEND_AST_UNPACK) { if (uses_named_args) { zend_error_noreturn(E_COMPILE_ERROR, - "Cannot combine named arguments and argument unpacking"); + "Cannot use argument unpacking after named arguments"); } uses_arg_unpack = 1; @@ -3492,16 +3492,11 @@ uint32_t zend_compile_args( } if (arg->kind == ZEND_AST_NAMED_ARG) { - if (uses_arg_unpack) { - zend_error_noreturn(E_COMPILE_ERROR, - "Cannot combine named arguments and argument unpacking"); - } - uses_named_args = 1; arg_name = zval_make_interned_string(zend_ast_get_zval(arg->child[0])); arg = arg->child[1]; - if (fbc) { + if (fbc && !uses_arg_unpack) { arg_num = zend_get_arg_num(fbc, arg_name); if (arg_num == arg_count + 1 && !may_have_undef) { /* Using named arguments, but passing in order. */ From 75cc982922f5833ab3f2769068405d81f60d9915 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 18 May 2021 14:47:36 +0200 Subject: [PATCH 2/2] Test another overwrite case --- Zend/tests/named_params/unpack_and_named_1.phpt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Zend/tests/named_params/unpack_and_named_1.phpt b/Zend/tests/named_params/unpack_and_named_1.phpt index 23bb679c08f75..1e08163724d4e 100644 --- a/Zend/tests/named_params/unpack_and_named_1.phpt +++ b/Zend/tests/named_params/unpack_and_named_1.phpt @@ -22,6 +22,11 @@ try { } catch (Error $e) { echo $e->getMessage(), "\n"; } +try { + test2(...[1, 'b' => 2], b: 20); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECT-- @@ -50,3 +55,4 @@ int(2) int(3) int(40) Named parameter $b overwrites previous argument +Named parameter $b overwrites previous argument