[Feature #19370] Prohibit nesting anonymous parameter forwarding
This commit is contained in:
parent
b641b7e640
commit
a9f0961831
6
parse.y
6
parse.y
@ -15009,6 +15009,8 @@ add_forwarding_args(struct parser_params *p)
|
|||||||
static void
|
static void
|
||||||
forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
|
forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
|
||||||
{
|
{
|
||||||
|
bool conflict = false;
|
||||||
|
|
||||||
struct vtable *vars, *args;
|
struct vtable *vars, *args;
|
||||||
|
|
||||||
vars = p->lvtbl->vars;
|
vars = p->lvtbl->vars;
|
||||||
@ -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)) {
|
while (vars && !DVARS_TERMINAL_P(vars->prev)) {
|
||||||
vars = vars->prev;
|
vars = vars->prev;
|
||||||
args = args->prev;
|
args = args->prev;
|
||||||
|
conflict |= (vtable_included(args, arg) && !(all && vtable_included(args, all)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -15032,6 +15035,9 @@ forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
compile_error(p, "no anonymous %s parameter", var);
|
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
|
#ifndef RIPPER
|
||||||
|
@ -76,6 +76,7 @@ class TestSyntax < Test::Unit::TestCase
|
|||||||
|
|
||||||
def test_anonymous_block_forwarding
|
def test_anonymous_block_forwarding
|
||||||
assert_syntax_error("def b; c(&); end", /no anonymous block parameter/)
|
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;'}")
|
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
begin;
|
begin;
|
||||||
def b(&); c(&) end
|
def b(&); c(&) end
|
||||||
@ -143,6 +144,9 @@ class TestSyntax < Test::Unit::TestCase
|
|||||||
def test_anonymous_rest_forwarding
|
def test_anonymous_rest_forwarding
|
||||||
assert_syntax_error("def b; c(*); end", /no anonymous rest parameter/)
|
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(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;'}")
|
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
begin;
|
begin;
|
||||||
def b(*); c(*) end
|
def b(*); c(*) end
|
||||||
@ -156,6 +160,9 @@ class TestSyntax < Test::Unit::TestCase
|
|||||||
def test_anonymous_keyword_rest_forwarding
|
def test_anonymous_keyword_rest_forwarding
|
||||||
assert_syntax_error("def b; c(**); end", /no anonymous keyword rest parameter/)
|
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(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;'}")
|
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
begin;
|
begin;
|
||||||
def b(**); c(**) end
|
def b(**); c(**) end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user