aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compile.c9
-rw-r--r--test/ruby/test_keyword.rb6
2 files changed, 14 insertions, 1 deletions
diff --git a/compile.c b/compile.c
index 98ee34afd0..c19112c853 100644
--- a/compile.c
+++ b/compile.c
@@ -5017,7 +5017,14 @@ setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
case NODE_ARGSPUSH: {
int next_is_list = (nd_type(argn->nd_head) == NODE_LIST);
VALUE argc = setup_args_core(iseq, args, argn->nd_head, 1, NULL, NULL);
- NO_CHECK(COMPILE(args, "args (cat: splat)", argn->nd_body));
+ if (nd_type(argn->nd_body) == NODE_LIST) {
+ /* This branch is needed to avoid "newarraykwsplat" [Bug #16442] */
+ int rest_len = compile_args(iseq, args, argn->nd_body, NULL, NULL);
+ ADD_INSN1(args, nd_line(argn), newarray, INT2FIX(rest_len));
+ }
+ else {
+ NO_CHECK(COMPILE(args, "args (cat: splat)", argn->nd_body));
+ }
if (flag) {
*flag |= VM_CALL_ARGS_SPLAT;
/* This is a dirty hack. It traverses the AST twice.
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 3d5cb2dd20..bfdec6fc74 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -4654,6 +4654,12 @@ class TestKeywordArguments < Test::Unit::TestCase
def test_splat_empty_hash_with_block_passing
assert_valid_syntax("bug15087(**{}, &nil)")
end
+
+ def test_do_not_use_newarraykwsplat
+ assert_equal([42, "foo", 424242], f2(*[], 42, **{}))
+ a = [1, 2, 3]
+ assert_equal([[1,2,3,4,5,6], "foo", 424242, {:k=>:k}], f7(*a, 4,5,6, k: :k))
+ end
end
class TestKeywordArgumentsSymProcRefinements < Test::Unit::TestCase