diff --git a/parse.y b/parse.y index 63624cb408..1c808bd60e 100644 --- a/parse.y +++ b/parse.y @@ -694,6 +694,11 @@ static NODE* node_newnode_with_locals(struct parser_params *, enum node_type, VA static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE, const rb_code_location_t*); #define rb_node_newnode(type, a1, a2, a3, loc) node_newnode(p, (type), (a1), (a2), (a3), (loc)) +/* Make a new temporal node, which should not be appeared in the + * result AST and does not have node_id and location. */ +static NODE* node_new_temporal(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2); +#define NODE_NEW_TEMPORAL(t,a0,a1,a2) node_new_temporal(p, (t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2)) + static NODE *nd_set_loc(NODE *nd, const YYLTYPE *loc); static int @@ -1223,10 +1228,13 @@ rescued_expr(struct parser_params *p, NODE *arg, NODE *rescue, static void restore_defun(struct parser_params *p, NODE *name) { - YYSTYPE c = {.val = name->nd_cval}; + NODE *save = name->nd_next; + YYSTYPE c = {.val = save->nd_cval}; p->cur_arg = name->nd_vid; p->ctxt.in_def = c.ctxt.in_def; p->ctxt.shareable_constant_value = c.ctxt.shareable_constant_value; + p->max_numparam = (int)save->nd_nth; + numparam_pop(p, save->nd_head); } static void @@ -2051,22 +2059,27 @@ expr : command_call | arg %prec tLBRACE_ARG ; -def_name : fname - { - ID fname = get_id($1); - ID cur_arg = p->cur_arg; - YYSTYPE c = {.ctxt = p->ctxt}; - numparam_name(p, fname); - local_push(p, 0); - p->cur_arg = 0; - p->ctxt.in_def = 1; - $$ = NEW_NODE(NODE_SELF, /*vid*/cur_arg, /*mid*/fname, /*cval*/c.val, &@$); - /*%%%*/ - /*% +def_name : fname + { + ID fname = get_id($1); + ID cur_arg = p->cur_arg; + YYSTYPE c = {.ctxt = p->ctxt}; + numparam_name(p, fname); + NODE *save = + NODE_NEW_TEMPORAL(NODE_SELF, + /*head*/numparam_push(p), + /*nth*/p->max_numparam, + /*cval*/c.val); + local_push(p, 0); + p->cur_arg = 0; + p->ctxt.in_def = 1; + $$ = NEW_NODE(NODE_SELF, /*vid*/cur_arg, /*mid*/fname, /*args*/save, &@$); + /*%%%*/ + /*% $$ = NEW_RIPPER(fname, get_value($1), $$, &NULL_LOC); %*/ - } - ; + } + ; defn_head : k_def def_name { @@ -10551,11 +10564,18 @@ yylex(YYSTYPE *lval, YYLTYPE *yylloc, struct parser_params *p) #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1)) static NODE* -node_newnode(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2, const rb_code_location_t *loc) +node_new_temporal(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2) { NODE *n = rb_ast_newnode(p->ast, type); rb_node_init(n, type, a0, a1, a2); + return n; +} + +static NODE* +node_newnode(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2, const rb_code_location_t *loc) +{ + NODE *n = node_new_temporal(p, type, a0, a1, a2); nd_set_loc(n, loc); nd_set_node_id(n, parser_get_node_id(p)); diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 2ada566c84..7553cd74a6 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -1706,6 +1706,7 @@ eom ] } + assert_valid_syntax("proc {def foo(_);end;_1}") assert_valid_syntax("p { [_1 **2] }") end diff --git a/version.h b/version.h index d68d096838..1034f6f505 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 4 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 204 +#define RUBY_PATCHLEVEL 205 #include "ruby/version.h" #include "ruby/internal/abi.h"