summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authorKazuki Tsujimoto <kazuki@callcc.net>2023-03-26 15:33:43 +0900
committerKazuki Tsujimoto <kazuki@callcc.net>2023-03-26 18:56:21 +0900
commit6c0925ba7017efde6091e2ec4f1a6be268166696 (patch)
tree86ff05358931208c74bdf994bfa004bbf3bd2bdd /parse.y
parent2f916812a9b818b432ee7c299e021ec62d4727fb (diff)
downloadruby-6c0925ba7017efde6091e2ec4f1a6be268166696.tar.gz
[Bug #19175] p_rest should be `assignable'
It should also check for duplicate names.
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y59
1 files changed, 26 insertions, 33 deletions
diff --git a/parse.y b/parse.y
index 4ef5b88407..27f944c1b2 100644
--- a/parse.y
+++ b/parse.y
@@ -761,9 +761,9 @@ static bool args_info_empty_p(struct rb_args_info *args);
static NODE *new_args(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*,const YYLTYPE*);
static NODE *new_args_tail(struct parser_params*,NODE*,ID,ID,const YYLTYPE*);
static NODE *new_array_pattern(struct parser_params *p, NODE *constant, NODE *pre_arg, NODE *aryptn, const YYLTYPE *loc);
-static NODE *new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID rest_arg, NODE *post_args, const YYLTYPE *loc);
+static NODE *new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc);
static NODE *new_find_pattern(struct parser_params *p, NODE *constant, NODE *fndptn, const YYLTYPE *loc);
-static NODE *new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID post_rest_arg, const YYLTYPE *loc);
+static NODE *new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc);
static NODE *new_hash_pattern(struct parser_params *p, NODE *constant, NODE *hshptn, const YYLTYPE *loc);
static NODE *new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, const YYLTYPE *loc);
@@ -1116,12 +1116,6 @@ new_array_pattern_tail(struct parser_params *p, VALUE pre_args, VALUE has_rest,
{
NODE *t;
- if (has_rest) {
- rest_arg = dispatch1(var_field, rest_arg ? rest_arg : Qnil);
- }
- else {
- rest_arg = Qnil;
- }
t = rb_node_newnode(NODE_ARYPTN, pre_args, rest_arg, post_args, &NULL_LOC);
add_mark_object(p, pre_args);
@@ -1144,9 +1138,6 @@ new_find_pattern_tail(struct parser_params *p, VALUE pre_rest_arg, VALUE args, V
{
NODE *t;
- pre_rest_arg = dispatch1(var_field, pre_rest_arg ? pre_rest_arg : Qnil);
- post_rest_arg = dispatch1(var_field, post_rest_arg ? post_rest_arg : Qnil);
-
t = rb_node_newnode(NODE_FNDPTN, pre_rest_arg, args, post_rest_arg, &NULL_LOC);
add_mark_object(p, pre_rest_arg);
add_mark_object(p, args);
@@ -1485,13 +1476,13 @@ static int looking_at_eol_p(struct parser_params *p);
%type <node> mlhs mlhs_head mlhs_basic mlhs_item mlhs_node mlhs_post mlhs_inner
%type <node> p_case_body p_cases p_top_expr p_top_expr_body
%type <node> p_expr p_as p_alt p_expr_basic p_find
-%type <node> p_args p_args_head p_args_tail p_args_post p_arg
+%type <node> p_args p_args_head p_args_tail p_args_post p_arg p_rest
%type <node> p_value p_primitive p_variable p_var_ref p_expr_ref p_const
%type <node> p_kwargs p_kwarg p_kw
%type <id> keyword_variable user_variable sym operation operation2 operation3
%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_bad_arg
%type <id> f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon
-%type <id> p_rest p_kwrest p_kwnorest p_any_kwrest p_kw_label
+%type <id> p_kwrest p_kwnorest p_any_kwrest p_kw_label
%type <id> f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var
%type <ctxt> lex_ctxt /* keep <ctxt> in ripper */
%token END_OF_INPUT 0 "end-of-input"
@@ -4439,7 +4430,7 @@ p_top_expr : p_top_expr_body
p_top_expr_body : p_expr
| p_expr ','
{
- $$ = new_array_pattern_tail(p, Qnone, 1, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, Qnone, 1, Qnone, Qnone, &@$);
$$ = new_array_pattern(p, Qnone, get_value($1), $$, &@$);
}
| p_expr ',' p_args
@@ -4523,7 +4514,7 @@ p_expr_basic : p_value
}
| p_const '(' rparen
{
- $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, Qnone, 0, Qnone, Qnone, &@$);
$$ = new_array_pattern(p, $1, Qnone, $$, &@$);
}
| p_const p_lbracket p_args rbracket
@@ -4555,7 +4546,7 @@ p_expr_basic : p_value
}
| p_const '[' rbracket
{
- $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, Qnone, 0, Qnone, Qnone, &@$);
$$ = new_array_pattern(p, $1, Qnone, $$, &@$);
}
| tLBRACK p_args rbracket
@@ -4568,7 +4559,7 @@ p_expr_basic : p_value
}
| tLBRACK rbracket
{
- $$ = new_array_pattern_tail(p, Qnone, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, Qnone, 0, Qnone, Qnone, &@$);
$$ = new_array_pattern(p, Qnone, Qnone, $$, &@$);
}
| tLBRACE
@@ -4599,22 +4590,22 @@ p_args : p_expr
{
/*%%%*/
NODE *pre_args = NEW_LIST($1, &@$);
- $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, pre_args, 0, Qnone, Qnone, &@$);
/*%
- $$ = new_array_pattern_tail(p, rb_ary_new_from_args(1, get_value($1)), 0, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, rb_ary_new_from_args(1, get_value($1)), 0, Qnone, Qnone, &@$);
%*/
}
| p_args_head
{
- $$ = new_array_pattern_tail(p, $1, 1, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, $1, 1, Qnone, Qnone, &@$);
}
| p_args_head p_arg
{
/*%%%*/
- $$ = new_array_pattern_tail(p, list_concat($1, $2), 0, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, list_concat($1, $2), 0, Qnone, Qnone, &@$);
/*%
VALUE pre_args = rb_ary_concat($1, get_value($2));
- $$ = new_array_pattern_tail(p, pre_args, 0, 0, Qnone, &@$);
+ $$ = new_array_pattern_tail(p, pre_args, 0, Qnone, Qnone, &@$);
%*/
}
| p_args_head p_rest
@@ -4660,11 +4651,18 @@ p_find : p_rest ',' p_args_post ',' p_rest
p_rest : tSTAR tIDENTIFIER
{
- $$ = $2;
+ /*%%%*/
+ error_duplicate_pattern_variable(p, $2, &@2);
+ $$ = assignable(p, $2, 0, &@$);
+ /*% %*/
+ /*% ripper: assignable(p, var_field(p, $2)) %*/
}
| tSTAR
{
+ /*%%%*/
$$ = 0;
+ /*% %*/
+ /*% ripper: Qnil %*/
}
;
@@ -12687,7 +12685,7 @@ new_array_pattern(struct parser_params *p, NODE *constant, NODE *pre_arg, NODE *
}
static NODE*
-new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID rest_arg, NODE *post_args, const YYLTYPE *loc)
+new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, NODE *rest_arg, NODE *post_args, const YYLTYPE *loc)
{
int saved_line = p->ruby_sourceline;
NODE *node;
@@ -12700,12 +12698,7 @@ new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, ID
apinfo->pre_args = pre_args;
if (has_rest) {
- if (rest_arg) {
- apinfo->rest_arg = assignable(p, rest_arg, 0, loc);
- }
- else {
- apinfo->rest_arg = NODE_SPECIAL_NO_NAME_REST;
- }
+ apinfo->rest_arg = rest_arg ? rest_arg : NODE_SPECIAL_NO_NAME_REST;
}
else {
apinfo->rest_arg = NULL;
@@ -12726,7 +12719,7 @@ new_find_pattern(struct parser_params *p, NODE *constant, NODE *fndptn, const YY
}
static NODE*
-new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID post_rest_arg, const YYLTYPE *loc)
+new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc)
{
int saved_line = p->ruby_sourceline;
NODE *node;
@@ -12736,9 +12729,9 @@ new_find_pattern_tail(struct parser_params *p, ID pre_rest_arg, NODE *args, ID p
node = NEW_NODE(NODE_FNDPTN, 0, tmpbuf, fpinfo, loc);
RB_OBJ_WRITTEN(p->ast, Qnil, tmpbuf);
- fpinfo->pre_rest_arg = pre_rest_arg ? assignable(p, pre_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
+ fpinfo->pre_rest_arg = pre_rest_arg ? pre_rest_arg : NODE_SPECIAL_NO_NAME_REST;
fpinfo->args = args;
- fpinfo->post_rest_arg = post_rest_arg ? assignable(p, post_rest_arg, 0, loc) : NODE_SPECIAL_NO_NAME_REST;
+ fpinfo->post_rest_arg = post_rest_arg ? post_rest_arg : NODE_SPECIAL_NO_NAME_REST;
p->ruby_sourceline = saved_line;
return node;