Fix using anonymous block in method accepting explicit keywords

Record block ID before vtable_pop, so the incorrect one doesn't
override it.

Fixes [Bug #18673]
This commit is contained in:
Jeremy Evans 2022-04-04 13:14:45 -07:00
parent 97ce030954
commit 3bb70a6924
Notes: git 2022-04-05 23:35:51 +09:00
2 changed files with 55 additions and 0 deletions

View File

@ -12081,6 +12081,7 @@ new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block,
struct vtable *vtargs = p->lvtbl->args; struct vtable *vtargs = p->lvtbl->args;
NODE *kwn = kw_args; NODE *kwn = kw_args;
if (block) block = vtargs->tbl[vtargs->pos-1];
vtable_pop(vtargs, !!block + !!kw_rest_arg); vtable_pop(vtargs, !!block + !!kw_rest_arg);
required_kw_vars = kw_vars = &vtargs->tbl[vtargs->pos]; required_kw_vars = kw_vars = &vtargs->tbl[vtargs->pos];
while (kwn) { while (kwn) {

View File

@ -75,6 +75,60 @@ class TestSyntax < Test::Unit::TestCase
a = nil a = nil
b{|c| a = c} b{|c| a = c}
assert_equal(1, a) assert_equal(1, a)
def inner
yield
end
def block_only(&)
inner(&)
end
assert_equal(1, block_only{1})
def pos(arg1, &)
inner(&)
end
assert_equal(2, pos(nil){2})
def pos_kwrest(arg1, **kw, &)
inner(&)
end
assert_equal(3, pos_kwrest(nil){3})
def no_kw(arg1, **nil, &)
inner(&)
end
assert_equal(4, no_kw(nil){4})
def rest_kw(*a, kwarg: 1, &)
inner(&)
end
assert_equal(5, rest_kw{5})
def kw(kwarg:1, &)
inner(&)
end
assert_equal(6, kw{6})
def pos_kw_kwrest(arg1, kwarg:1, **kw, &)
inner(&)
end
assert_equal(7, pos_kw_kwrest(nil){7})
def pos_rkw(arg1, kwarg1:, &)
inner(&)
end
assert_equal(8, pos_rkw(nil, kwarg1: nil){8})
def all(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, &)
inner(&)
end
assert_equal(9, all(nil, nil, nil, nil, okw1: nil, okw2: nil){9})
def all_kwrest(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, **kw, &)
inner(&)
end
assert_equal(10, all_kwrest(nil, nil, nil, nil, okw1: nil, okw2: nil){10})
end; end;
end end