summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast.c4
-rw-r--r--compile.c26
-rw-r--r--node.c7
-rw-r--r--parse.y2
4 files changed, 23 insertions, 16 deletions
diff --git a/ast.c b/ast.c
index 5945df95ce..3e25c89a55 100644
--- a/ast.c
+++ b/ast.c
@@ -634,10 +634,12 @@ node_children(rb_ast_t *ast, NODE *node)
case NODE_ARYPTN:
{
struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
+ VALUE rest = NODE_NAMED_REST_P(apinfo->rest_arg) ? NEW_CHILD(ast, apinfo->rest_arg) :
+ ID2SYM(rb_intern("NODE_SPECIAL_NO_NAME_REST"));
return rb_ary_new_from_args(4,
NEW_CHILD(ast, node->nd_pconst),
NEW_CHILD(ast, apinfo->pre_args),
- NEW_CHILD(ast, apinfo->rest_arg),
+ rest,
NEW_CHILD(ast, apinfo->post_args));
}
case NODE_HSHPTN:
diff --git a/compile.c b/compile.c
index 6d6d9e1c8f..2dbfb5497e 100644
--- a/compile.c
+++ b/compile.c
@@ -5305,8 +5305,8 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
const int post_args_num = apinfo->post_args ? rb_long2int(apinfo->post_args->nd_alen) : 0;
const int min_argc = pre_args_num + post_args_num;
- const int use_rest_num = apinfo->rest_arg && ((nd_type(apinfo->rest_arg) != NODE_BEGIN) ||
- (nd_type(apinfo->rest_arg) == NODE_BEGIN && post_args_num > 0));
+ const int use_rest_num = apinfo->rest_arg && (NODE_NAMED_REST_P(apinfo->rest_arg) ||
+ (!NODE_NAMED_REST_P(apinfo->rest_arg) && post_args_num > 0));
LABEL *match_failed, *type_error, *fin;
int i;
@@ -5354,17 +5354,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
}
if (apinfo->rest_arg) {
- if (nd_type(apinfo->rest_arg) == NODE_BEGIN) {
- if (post_args_num > 0) {
- ADD_INSN(ret, line, dup);
- ADD_SEND(ret, line, idLength, INT2FIX(0));
- ADD_INSN1(ret, line, putobject, INT2FIX(min_argc));
- ADD_SEND(ret, line, idMINUS, INT2FIX(1));
- ADD_INSN1(ret, line, setn, INT2FIX(2));
- ADD_INSN(ret, line, pop);
- }
- }
- else {
+ if (NODE_NAMED_REST_P(apinfo->rest_arg)) {
ADD_INSN(ret, line, dup);
ADD_INSN1(ret, line, putobject, INT2FIX(pre_args_num));
ADD_INSN1(ret, line, topn, INT2FIX(1));
@@ -5377,6 +5367,16 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
iseq_compile_pattern_each(iseq, ret, apinfo->rest_arg, in_alt_pattern);
ADD_INSNL(ret, line, branchunless, match_failed);
}
+ else {
+ if (post_args_num > 0) {
+ ADD_INSN(ret, line, dup);
+ ADD_SEND(ret, line, idLength, INT2FIX(0));
+ ADD_INSN1(ret, line, putobject, INT2FIX(min_argc));
+ ADD_SEND(ret, line, idMINUS, INT2FIX(1));
+ ADD_INSN1(ret, line, setn, INT2FIX(2));
+ ADD_INSN(ret, line, pop);
+ }
+ }
}
args = apinfo->post_args;
diff --git a/node.c b/node.c
index eb88efc61a..323debc2a3 100644
--- a/node.c
+++ b/node.c
@@ -1040,7 +1040,12 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
F_NODE(nd_pconst, "constant");
F_NODE(nd_apinfo->pre_args, "pre arguments");
- F_NODE(nd_apinfo->rest_arg, "rest argument");
+ if (NODE_NAMED_REST_P(node->nd_apinfo->rest_arg)) {
+ F_NODE(nd_apinfo->rest_arg, "rest argument");
+ }
+ else {
+ F_MSG(nd_apinfo->rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
+ }
LAST_NODE;
F_NODE(nd_apinfo->post_args, "post arguments");
return;
diff --git a/parse.y b/parse.y
index e131457d57..bd4694b0a0 100644
--- a/parse.y
+++ b/parse.y
@@ -11037,7 +11037,7 @@ new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID
if (rest_arg) {
apinfo->rest_arg = assignable(p, rest_arg, 0, loc);
} else {
- apinfo->rest_arg = NEW_BEGIN(0, loc);
+ apinfo->rest_arg = NODE_SPECIAL_NO_NAME_REST;
}
} else {
apinfo->rest_arg = NULL;