10000 [Feature #19370] Prohibit nesting anonymous parameter forwarding · github/ruby@a9f0961 · GitHub
[go: up one dir, main page]

Skip to content

Commit a9f0961

Browse files
committed
[Feature #19370] Prohibit nesting anonymous parameter forwarding
1 parent b641b7e commit a9f0961

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

parse.y

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15009,6 +15009,8 @@ add_forwarding_args(struct parser_params *p)
1500915009
static void
1501015010
forwarding_arg_check(struct parser_params *p, ID arg, ID all, const char *var)
1501115011
{
15012+
bool conflict = false;
15013+
1501215014
struct vtable *vars, *args;
1501315015

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

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

1503715043
#ifndef RIPPER

test/ruby/test_syntax.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def test_script_lines_encoding
7676

7777
def test_anonymous_block_forwarding
7878
assert_syntax_error("def b; c(&); end", /no anonymous block parameter/)
79+
assert_syntax_error("def b(&) ->(&) {c(&)} end", /anonymous block parameter is also used/)
7980
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
8081
begin;
8182
def b(&); c(&) end
@@ -143,6 +144,9 @@ def all_kwrest(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, **
143144
def test_anonymous_rest_forwarding
144145
assert_syntax_error("def b; c(*); end", /no anonymous rest parameter/)
145146
assert_syntax_error("def b; c(1, *); end", /no anonymous rest parameter/)
147+
assert_syntax_error("def b(*) ->(*) {c(*)} end", /anonymous rest parameter is also used/)
148+
assert_syntax_error("def b(a, *) ->(*) {c(1, *)} end", /anonymous rest parameter is also used/)
149+
assert_syntax_error("def b(*) ->(a, *) {c(*)} end", /anonymous rest parameter is also used/)
146150
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
147151
begin;
148152
def b(*); c(*) end
@@ -156,6 +160,9 @@ def d(*); b(*, *) end
156160
def test_anonymous_keyword_rest_forwarding
157161
assert_syntax_error("def b; c(**); end", /no anonymous keyword rest parameter/)
158162
assert_syntax_error("def b; c(k: 1, **); end", /no anonymous keyword rest parameter/)
163+
assert_syntax_error("def b(**) ->(**) {c(**)} end", /anonymous keyword rest parameter is also used/)
164+
assert_syntax_error("def b(k:, **) ->(**) {c(k: 1, **)} end", /anonymous keyword rest parameter is also used/)
165+
assert_syntax_error("def b(**) ->(k:, **) {c(**)} end", /anonymous keyword rest parameter is also used/)
159166
assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}")
160167
begin;
161168
def b(**); c(**) end

0 commit comments

Comments
 (0)
0