summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--parse.y20
-rw-r--r--test/ruby/test_syntax.rb17
2 files changed, 21 insertions, 16 deletions
diff --git a/parse.y b/parse.y
index 0a2aa6f1bc..5133b6de82 100644
--- a/parse.y
+++ b/parse.y
@@ -944,11 +944,7 @@ static void numparam_pop(struct parser_params *p, NODE *prev_inner);
#endif
#define idFWD_REST '*'
-#ifdef RUBY3_KEYWORDS
#define idFWD_KWREST idPow /* Use simple "**", as tDSTAR is "**arg" */
-#else
-#define idFWD_KWREST 0
-#endif
#define idFWD_BLOCK '&'
#define RE_OPTION_ONCE (1<<16)
@@ -12581,7 +12577,7 @@ new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, N
args->opt_args = opt_args;
- args->ruby2_keywords = args->forwarding;
+ args->ruby2_keywords = 0;
p->ruby_sourceline = saved_line;
nd_set_loc(tail, loc);
@@ -13266,9 +13262,7 @@ static int
check_forwarding_args(struct parser_params *p)
{
if (local_id(p, idFWD_REST) &&
-#if idFWD_KWREST
local_id(p, idFWD_KWREST) &&
-#endif
local_id(p, idFWD_BLOCK)) return TRUE;
compile_error(p, "unexpected ...");
return FALSE;
@@ -13278,9 +13272,7 @@ static void
add_forwarding_args(struct parser_params *p)
{
arg_var(p, idFWD_REST);
-#if idFWD_KWREST
arg_var(p, idFWD_KWREST);
-#endif
arg_var(p, idFWD_BLOCK);
}
@@ -13288,15 +13280,11 @@ add_forwarding_args(struct parser_params *p)
static NODE *
new_args_forward_call(struct parser_params *p, NODE *leading, const YYLTYPE *loc, const YYLTYPE *argsloc)
{
- NODE *splat = NEW_SPLAT(NEW_LVAR(idFWD_REST, loc), loc);
-#if idFWD_KWREST
+ NODE *rest = NEW_LVAR(idFWD_REST, loc);
NODE *kwrest = list_append(p, NEW_LIST(0, loc), NEW_LVAR(idFWD_KWREST, loc));
-#endif
NODE *block = NEW_BLOCK_PASS(NEW_LVAR(idFWD_BLOCK, loc), loc);
- NODE *args = leading ? rest_arg_append(p, leading, splat, argsloc) : splat;
-#if idFWD_KWREST
- args = arg_append(p, splat, new_hash(p, kwrest, loc), loc);
-#endif
+ NODE *args = leading ? rest_arg_append(p, leading, rest, loc) : NEW_SPLAT(rest, loc);
+ args = arg_append(p, args, new_hash(p, kwrest, loc), loc);
return arg_blk_pass(args, block);
}
#endif
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 251448ec01..a5106e0353 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -171,6 +171,23 @@ class TestSyntax < Test::Unit::TestCase
end;
end
+ def test_argument_forwarding_with_anon_rest_kwrest_and_block
+ assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
+ begin;
+ def args(*args); args end
+ def kw(**kw); kw end
+ def block(&block); block end
+ def deconstruct(...); [args(*), kw(**), block(&)&.call] end
+ assert_equal([[], {}, nil], deconstruct)
+ assert_equal([[1], {}, nil], deconstruct(1))
+ assert_equal([[1, 2], {}, nil], deconstruct(1, 2))
+ assert_equal([[], {x: 1}, nil], deconstruct(x: 1))
+ assert_equal([[], {x: 1, y: 2}, nil], deconstruct(x: 1, y: 2))
+ assert_equal([[], {}, "x"], deconstruct { "x" })
+ assert_equal([[1, 2], {x: 3, y: 4}, "x"], deconstruct(1, 2, x: 3, y: 4) { "x" })
+ end;
+ end
+
def test_newline_in_block_parameters
bug = '[ruby-dev:45292]'
["", "a", "a, b"].product(["", ";x", [";", "x"]]) do |params|