summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-10-31 15:20:48 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-10-31 18:27:55 +0900
commit13a9597c7ca83fced5738e9345660ae6aef87eb7 (patch)
tree5b48e3716d6b66533262abee83ccbf6b6d475fe2 /parse.y
parent7da6e9b3ecc520c272e06426407626284f0f021c (diff)
Argument forwarding definition without parentheses [Bug #18267]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5065
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y49
1 files changed, 20 insertions, 29 deletions
diff --git a/parse.y b/parse.y
index acea824473..d3eb42e33f 100644
--- a/parse.y
+++ b/parse.y
@@ -675,7 +675,6 @@ static int local_id_ref(struct parser_params*, ID, ID **);
#ifndef RIPPER
static ID internal_id(struct parser_params*);
static NODE *new_args_forward_call(struct parser_params*, NODE*, const YYLTYPE*, const YYLTYPE*);
-static NODE *new_args_forward_def(struct parser_params*, NODE*, const YYLTYPE*);
#endif
static int check_forwarding_args(struct parser_params*);
static void add_forwarding_args(struct parser_params *p);
@@ -5128,26 +5127,6 @@ f_paren_args : '(' f_args rparen
SET_LEX_STATE(EXPR_BEG);
p->command_start = TRUE;
}
- | '(' f_arg ',' args_forward rparen
- {
- add_forwarding_args(p);
- /*%%%*/
- $$ = new_args_forward_def(p, $2, &@$);
- /*% %*/
- /*% ripper: paren!(params!($2, Qnone, $4, Qnone, Qnone, Qnone, Qnone)) %*/
- SET_LEX_STATE(EXPR_BEG);
- p->command_start = TRUE;
- }
- | '(' args_forward rparen
- {
- add_forwarding_args(p);
- /*%%%*/
- $$ = new_args_forward_def(p, 0, &@$);
- /*% %*/
- /*% ripper: paren!(params!(Qnone, Qnone, $2, Qnone, Qnone, Qnone, Qnone)) %*/
- SET_LEX_STATE(EXPR_BEG);
- p->command_start = TRUE;
- }
;
f_arglist : f_paren_args
@@ -5181,6 +5160,11 @@ args_tail : f_kwarg ',' f_kwrest opt_f_block_arg
{
$$ = new_args_tail(p, Qnone, Qnone, $1, &@1);
}
+ | args_forward
+ {
+ add_forwarding_args(p);
+ $$ = new_args_tail(p, Qnone, $1, ID2VAL(idFWD_BLOCK), &@1);
+ }
;
opt_args_tail : ',' args_tail
@@ -5259,7 +5243,7 @@ f_args : f_arg ',' f_optarg ',' f_rest_arg opt_args_tail
args_forward : tBDOT3
{
/*%%%*/
- $$ = idDot3;
+ $$ = idFWD_KWREST;
/*% %*/
/*% ripper: args_forward! %*/
}
@@ -9653,6 +9637,12 @@ parser_yylex(struct parser_params *p)
if ((c = nextc(p)) == '.') {
if ((c = nextc(p)) == '.') {
if (p->lex.paren_nest == 0 && looking_at_eol_p(p)) {
+ if (p->ctxt.in_argdef || /* def foo a, ... */
+ IS_lex_state_for(last_state, EXPR_ENDFN) || /* def foo ... */
+ 0) {
+ SET_LEX_STATE(EXPR_ENDARG);
+ return tBDOT3;
+ }
rb_warn0("... at EOL, should be parenthesized?");
}
else if (p->lex.lpar_beg >= 0 && p->lex.lpar_beg+1 == p->lex.paren_nest) {
@@ -11967,6 +11957,14 @@ new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, N
int saved_line = p->ruby_sourceline;
struct rb_args_info *args = tail->nd_ainfo;
+ if (args->block_arg == idFWD_BLOCK) {
+ if (rest_arg) {
+ yyerror1(&tail->nd_loc, "... after rest argument");
+ return tail;
+ }
+ rest_arg = idFWD_REST;
+ }
+
args->pre_args_num = pre_args ? rb_long2int(pre_args->nd_plen) : 0;
args->pre_init = pre_args ? pre_args->nd_next : 0;
@@ -12697,13 +12695,6 @@ new_args_forward_call(struct parser_params *p, NODE *leading, const YYLTYPE *loc
#endif
return arg_blk_pass(args, block);
}
-
-static NODE *
-new_args_forward_def(struct parser_params *p, NODE *leading, const YYLTYPE *loc)
-{
- NODE *n = new_args_tail(p, Qnone, idFWD_KWREST, idFWD_BLOCK, loc);
- return new_args(p, leading, Qnone, idFWD_REST, Qnone, n, loc);
-}
#endif
static NODE *