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;