Skip to content

Commit

Permalink
[Feature #19370] Prohibit nesting anonymous parameter forwarding
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu committed Dec 25, 2023
1 parent b641b7e commit a9f0961
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
6 changes: 6 additions & 0 deletions parse.y
Expand Up @@ -15009,6 +15009,8 @@ add_forwarding_args(struct parser_params *p)
static void
forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
{
bool conflict = false;

struct vtable *vars, *args;

vars = p->lvtbl->vars;
Expand All @@ -15017,6 +15019,7 @@ forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
while (vars && !DVARS_TERMINAL_P(vars->prev)) {
vars = vars->prev;
args = args->prev;
conflict |= (vtable_included(args, arg) && !(all && vtable_included(args, all)));
}

bool found = false;
Expand All @@ -15032,6 +15035,9 @@ forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
if (!found) {
compile_error(p, "no anonymous %s parameter", var);
}
else if (conflict) {
compile_error(p, "anonymous %s parameter is also used within block", var);
}
}

#ifndef RIPPER
Expand Down
7 changes: 7 additions & 0 deletions test/ruby/test_syntax.rb
Expand Up @@ -76,6 +76,7 @@ def test_script_lines_encoding

def test_anonymous_block_forwarding
assert_syntax_error("def b; c(&); end", /no anonymous block parameter/)
assert_syntax_error("def b(&) ->(&) {c(&)} end", /anonymous block parameter is also used/)
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
def b(&); c(&) end
Expand Down Expand Up @@ -143,6 +144,9 @@ def all_kwrest(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, **
def test_anonymous_rest_forwarding
assert_syntax_error("def b; c(*); end", /no anonymous rest parameter/)
assert_syntax_error("def b; c(1, *); end", /no anonymous rest parameter/)
assert_syntax_error("def b(*) ->(*) {c(*)} end", /anonymous rest parameter is also used/)
assert_syntax_error("def b(a, *) ->(*) {c(1, *)} end", /anonymous rest parameter is also used/)
assert_syntax_error("def b(*) ->(a, *) {c(*)} end", /anonymous rest parameter is also used/)
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
def b(*); c(*) end
Expand All @@ -156,6 +160,9 @@ def d(*); b(*, *) end
def test_anonymous_keyword_rest_forwarding
assert_syntax_error("def b; c(**); end", /no anonymous keyword rest parameter/)
assert_syntax_error("def b; c(k: 1, **); end", /no anonymous keyword rest parameter/)
assert_syntax_error("def b(**) ->(**) {c(**)} end", /anonymous keyword rest parameter is also used/)
assert_syntax_error("def b(k:, **) ->(**) {c(k: 1, **)} end", /anonymous keyword rest parameter is also used/)
assert_syntax_error("def b(**) ->(k:, **) {c(**)} end", /anonymous keyword rest parameter is also used/)
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
begin;
def b(**); c(**) end
Expand Down

0 comments on commit a9f0961

Please sign in to comment.