Skip to content

Commit

Permalink
[Bug #20218] Reject keyword arguments in index
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu committed Mar 17, 2024
1 parent df5ef28 commit 0d5b165
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 563 deletions.
4 changes: 0 additions & 4 deletions bootstraptest/test_method.rb
Expand Up @@ -1088,10 +1088,6 @@ class C
'ok'
end
}
assert_equal 'ok', %q{
[0][0, &proc{}] += 21
'ok'
}, '[ruby-core:30534]'

# should not cache when splat
assert_equal 'ok', %q{
Expand Down
33 changes: 30 additions & 3 deletions parse.y
Expand Up @@ -13872,12 +13872,38 @@ new_bv(struct parser_params *p, ID name)
dyna_var(p, name);
}

static void
aryset_check(struct parser_params *p, NODE *args)
{
NODE *block = 0, *kwds = 0;
if (args && nd_type_p(args, NODE_BLOCK_PASS)) {
block = RNODE_BLOCK_PASS(args)->nd_body;
args = RNODE_BLOCK_PASS(args)->nd_head;
}
if (args && nd_type_p(args, NODE_ARGSCAT)) {
args = RNODE_ARGSCAT(args)->nd_body;
}
if (args && nd_type_p(args, NODE_ARGSPUSH)) {
kwds = RNODE_ARGSPUSH(args)->nd_body;
}
else {
for (NODE *next = args; next && nd_type_p(next, NODE_LIST);
next = RNODE_LIST(next)->nd_next) {
kwds = RNODE_LIST(next)->nd_head;
}
}
if (kwds && nd_type_p(kwds, NODE_HASH) && !RNODE_HASH(kwds)->nd_brace) {
yyerror1(&kwds->nd_loc, "keyword arg given in index");
}
if (block) {
yyerror1(&block->nd_loc, "block arg given in index");
}
}

static NODE *
aryset(struct parser_params *p, NODE *recv, NODE *idx, const YYLTYPE *loc)
{
if (idx && nd_type_p(idx, NODE_BLOCK_PASS)) {
compile_error(p, "block arg given in index");
}
aryset_check(p, idx);
return NEW_ATTRASGN(recv, tASET, idx, loc);
}

Expand Down Expand Up @@ -15334,6 +15360,7 @@ new_ary_op_assign(struct parser_params *p, NODE *ary,
{
NODE *asgn;

aryset_check(p, args);
args = make_list(args, args_loc);
asgn = NEW_OP_ASGN1(ary, op, args, rhs, loc);
fixpos(asgn, ary);
Expand Down
12 changes: 6 additions & 6 deletions test/prism/fixtures/arrays.txt
Expand Up @@ -113,17 +113,17 @@ foo.foo[bar] ||= 1

foo.foo[bar] &&= 1

foo[bar, &baz] += 1
# foo[bar, &baz] += 1

foo[bar, &baz] ||= 1
# foo[bar, &baz] ||= 1

foo[bar, &baz] &&= 1
# foo[bar, &baz] &&= 1

foo.foo[bar, &baz] += 1
# foo.foo[bar, &baz] += 1

foo.foo[bar, &baz] ||= 1
# foo.foo[bar, &baz] ||= 1

foo.foo[bar, &baz] &&= 1
# foo.foo[bar, &baz] &&= 1

def f(*); a[*]; end

Expand Down
328 changes: 1 addition & 327 deletions test/prism/snapshots/arrays.txt

Large diffs are not rendered by default.

216 changes: 106 additions & 110 deletions test/ruby/test_call.rb
Expand Up @@ -133,125 +133,127 @@ def []=(*a, **b, &c) @set = [a, b, c] end
kw = {}
b = lambda{}

message = /keyword arg given in index/

# +=, without block, non-popped
assert_equal([[], {}, nil, [4], {}, nil], h.v{h[**kw] += 1})
assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, **kw] += 1})
assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, *a, **kw] += 1})
assert_equal([[], {kw: 5}, nil, [4], {kw: 5}, nil], h.v{h[kw: 5] += 1})
assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1})
assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1})
assert_equal([[0], {kw: 5, a: 2}, nil, [0, 4], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] += 1})
assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 4], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] += 1})
assert_syntax_error(%q{h[**kw] += 1}, message)
assert_syntax_error(%q{h[0, **kw] += 1}, message)
assert_syntax_error(%q{h[0, *a, **kw] += 1}, message)
assert_syntax_error(%q{h[kw: 5] += 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] += 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] += 1}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2] += 1}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] += 1}, message)

# +=, with block, non-popped
assert_equal([[], {}, b, [4], {}, b], h.v{h[**kw, &b] += 1})
assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, **kw, &b] += 1})
assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, *a, **kw, &b] += 1})
assert_equal([[], {kw: 5}, b, [4], {kw: 5}, b], h.v{h[kw: 5, &b] += 1})
assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1})
assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1})
assert_equal([[0], {kw: 5, a: 2}, b, [0, 4], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] += 1})
assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 4], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1})
assert_syntax_error(%q{h[**kw, &b] += 1}, message)
assert_syntax_error(%q{h[0, **kw, &b] += 1}, message)
assert_syntax_error(%q{h[0, *a, **kw, &b] += 1}, message)
assert_syntax_error(%q{h[kw: 5, &b] += 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] += 1}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1}, message)

# +=, without block, popped
assert_equal([[], {}, nil, [4], {}, nil], h.v{h[**kw] += 1; nil})
assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, **kw] += 1; nil})
assert_equal([[0], {}, nil, [0, 4], {}, nil], h.v{h[0, *a, **kw] += 1; nil})
assert_equal([[], {kw: 5}, nil, [4], {kw: 5}, nil], h.v{h[kw: 5] += 1; nil})
assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1; nil})
assert_equal([[], {kw: 5, a: 2}, nil, [4], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] += 1; nil})
assert_equal([[0], {kw: 5, a: 2}, nil, [0, 4], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] += 1; nil})
assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 4], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] += 1; nil})
assert_syntax_error(%q{h[**kw] += 1; nil}, message)
assert_syntax_error(%q{h[0, **kw] += 1; nil}, message)
assert_syntax_error(%q{h[0, *a, **kw] += 1; nil}, message)
assert_syntax_error(%q{h[kw: 5] += 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] += 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] += 1; nil}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2] += 1; nil}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] += 1; nil}, message)

# +=, with block, popped
assert_equal([[], {}, b, [4], {}, b], h.v{h[**kw, &b] += 1; nil})
assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, **kw, &b] += 1; nil})
assert_equal([[0], {}, b, [0, 4], {}, b], h.v{h[0, *a, **kw, &b] += 1; nil})
assert_equal([[], {kw: 5}, b, [4], {kw: 5}, b], h.v{h[kw: 5, &b] += 1; nil})
assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1; nil})
assert_equal([[], {kw: 5, a: 2}, b, [4], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] += 1; nil})
assert_equal([[0], {kw: 5, a: 2}, b, [0, 4], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] += 1; nil})
assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 4], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1; nil})
assert_syntax_error(%q{h[**kw, &b] += 1; nil}, message)
assert_syntax_error(%q{h[0, **kw, &b] += 1; nil}, message)
assert_syntax_error(%q{h[0, *a, **kw, &b] += 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, &b] += 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] += 1; nil}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] += 1; nil}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] += 1; nil}, message)

# &&=, without block, non-popped
assert_equal([[], {}, nil, [1], {}, nil], h.v{h[**kw] &&= 1})
assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, **kw] &&= 1})
assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, *a, **kw] &&= 1})
assert_equal([[], {kw: 5}, nil, [1], {kw: 5}, nil], h.v{h[kw: 5] &&= 1})
assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1})
assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1})
assert_equal([[0], {kw: 5, a: 2}, nil, [0, 1], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] &&= 1})
assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 1], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1})
assert_syntax_error(%q{h[**kw] &&= 1}, message)
assert_syntax_error(%q{h[0, **kw] &&= 1}, message)
assert_syntax_error(%q{h[0, *a, **kw] &&= 1}, message)
assert_syntax_error(%q{h[kw: 5] &&= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2] &&= 1}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1}, message)

# &&=, with block, non-popped
assert_equal([[], {}, b, [1], {}, b], h.v{h[**kw, &b] &&= 1})
assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, **kw, &b] &&= 1})
assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, *a, **kw, &b] &&= 1})
assert_equal([[], {kw: 5}, b, [1], {kw: 5}, b], h.v{h[kw: 5, &b] &&= 1})
assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1})
assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1})
assert_equal([[0], {kw: 5, a: 2}, b, [0, 1], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] &&= 1})
assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 1], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1})
assert_syntax_error(%q{h[**kw, &b] &&= 1}, message)
assert_syntax_error(%q{h[0, **kw, &b] &&= 1}, message)
assert_syntax_error(%q{h[0, *a, **kw, &b] &&= 1}, message)
assert_syntax_error(%q{h[kw: 5, &b] &&= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] &&= 1}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1}, message)

# &&=, without block, popped
assert_equal([[], {}, nil, [1], {}, nil], h.v{h[**kw] &&= 1; nil})
assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, **kw] &&= 1; nil})
assert_equal([[0], {}, nil, [0, 1], {}, nil], h.v{h[0, *a, **kw] &&= 1; nil})
assert_equal([[], {kw: 5}, nil, [1], {kw: 5}, nil], h.v{h[kw: 5] &&= 1; nil})
assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1; nil})
assert_equal([[], {kw: 5, a: 2}, nil, [1], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] &&= 1; nil})
assert_equal([[0], {kw: 5, a: 2}, nil, [0, 1], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] &&= 1; nil})
assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil, [0, 1], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1; nil})
assert_syntax_error(%q{h[**kw] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, **kw] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, **kw] &&= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5] &&= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] &&= 1; nil}, message)

# &&=, with block, popped
assert_equal([[], {}, b, [1], {}, b], h.v{h[**kw, &b] &&= 1; nil})
assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, **kw, &b] &&= 1; nil})
assert_equal([[0], {}, b, [0, 1], {}, b], h.v{h[0, *a, **kw, &b] &&= 1; nil})
assert_equal([[], {kw: 5}, b, [1], {kw: 5}, b], h.v{h[kw: 5, &b] &&= 1; nil})
assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1; nil})
assert_equal([[], {kw: 5, a: 2}, b, [1], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] &&= 1; nil})
assert_equal([[0], {kw: 5, a: 2}, b, [0, 1], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] &&= 1; nil})
assert_equal([[0], {kw: 5, a: 2, b: 3}, b, [0, 1], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1; nil})
assert_syntax_error(%q{h[**kw, &b] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, **kw, &b] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, **kw, &b] &&= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, &b] &&= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] &&= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] &&= 1; nil}, message)

# ||=, without block, non-popped
assert_equal([[], {}, nil], h.v{h[**kw] ||= 1})
assert_equal([[0], {}, nil], h.v{h[0, **kw] ||= 1})
assert_equal([[0], {}, nil], h.v{h[0, *a, **kw] ||= 1})
assert_equal([[], {kw: 5}, nil], h.v{h[kw: 5] ||= 1})
assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1})
assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1})
assert_equal([[0], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] ||= 1})
assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1})
assert_syntax_error(%q{h[**kw] ||= 1}, message)
assert_syntax_error(%q{h[0, **kw] ||= 1}, message)
assert_syntax_error(%q{h[0, *a, **kw] ||= 1}, message)
assert_syntax_error(%q{h[kw: 5] ||= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2] ||= 1}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1}, message)

# ||=, with block, non-popped
assert_equal([[], {}, b], h.v{h[**kw, &b] ||= 1})
assert_equal([[0], {}, b], h.v{h[0, **kw, &b] ||= 1})
assert_equal([[0], {}, b], h.v{h[0, *a, **kw, &b] ||= 1})
assert_equal([[], {kw: 5}, b], h.v{h[kw: 5, &b] ||= 1})
assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1})
assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1})
assert_equal([[0], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] ||= 1})
assert_equal([[0], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1})
assert_syntax_error(%q{h[**kw, &b] ||= 1}, message)
assert_syntax_error(%q{h[0, **kw, &b] ||= 1}, message)
assert_syntax_error(%q{h[0, *a, **kw, &b] ||= 1}, message)
assert_syntax_error(%q{h[kw: 5, &b] ||= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] ||= 1}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1}, message)

# ||=, without block, popped
assert_equal([[], {}, nil], h.v{h[**kw] ||= 1; nil})
assert_equal([[0], {}, nil], h.v{h[0, **kw] ||= 1; nil})
assert_equal([[0], {}, nil], h.v{h[0, *a, **kw] ||= 1; nil})
assert_equal([[], {kw: 5}, nil], h.v{h[kw: 5] ||= 1; nil})
assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1; nil})
assert_equal([[], {kw: 5, a: 2}, nil], h.v{h[kw: 5, a: 2] ||= 1; nil})
assert_equal([[0], {kw: 5, a: 2}, nil], h.v{h[0, kw: 5, a: 2] ||= 1; nil})
assert_equal([[0], {kw: 5, a: 2, nil: 3}, nil], h.v{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1; nil})
assert_syntax_error(%q{h[**kw] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, **kw] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, **kw] ||= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5] ||= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, nil: 3] ||= 1; nil}, message)

# ||=, with block, popped
assert_equal([[], {}, b], h.v{h[**kw, &b] ||= 1; nil})
assert_equal([[0], {}, b], h.v{h[0, **kw, &b] ||= 1; nil})
assert_equal([[0], {}, b], h.v{h[0, *a, **kw, &b] ||= 1; nil})
assert_equal([[], {kw: 5}, b], h.v{h[kw: 5, &b] ||= 1; nil})
assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1; nil})
assert_equal([[], {kw: 5, a: 2}, b], h.v{h[kw: 5, a: 2, &b] ||= 1; nil})
assert_equal([[0], {kw: 5, a: 2}, b], h.v{h[0, kw: 5, a: 2, &b] ||= 1; nil})
assert_equal([[0], {kw: 5, a: 2, b: 3}, b], h.v{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1; nil})
assert_syntax_error(%q{h[**kw, &b] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, **kw, &b] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, **kw, &b] ||= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, &b] ||= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1; nil}, message)
assert_syntax_error(%q{h[kw: 5, a: 2, &b] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, kw: 5, a: 2, &b] ||= 1; nil}, message)
assert_syntax_error(%q{h[0, *a, kw: 5, a: 2, b: 3, &b] ||= 1; nil}, message)

end

Expand All @@ -265,20 +267,12 @@ def test_kwsplat_block_order_op_asgn
def o.[](...) 2 end
def o.[]=(...) end

o[kw: 1] += 1
assert_equal([], ary)

o[**o] += 1
assert_equal([:to_hash], ary)

ary.clear
o[**o, &o] += 1
# to_proc called twice because no VM instruction for coercing to proc
assert_equal([:to_hash, :to_proc, :to_proc], ary)
message = /keyword arg given in index/

ary.clear
o[*o, **o, &o] += 1
assert_equal([:to_a, :to_hash, :to_proc, :to_proc], ary)
assert_syntax_error(%q{o[kw: 1] += 1}, message)
assert_syntax_error(%q{o[**o] += 1}, message)
assert_syntax_error(%q{o[**o, &o] += 1}, message)
assert_syntax_error(%q{o[*o, **o, &o] += 1}, message)
end

def test_call_op_asgn_keywords_mutable
Expand All @@ -295,10 +289,12 @@ def [](*a, **b)
def []=(*a, **b) @set = [a, b] end
end.new

message = /keyword arg given in index/

a = []
kw = {}

assert_equal([[2], {b: 5}, [2, 4], {b: 5}], h.v{h[*a, 2, b: 5, **kw] += 1})
assert_syntax_error(%q{h[*a, 2, b: 5, **kw] += 1}, message)
end

def test_call_splat_order
Expand Down

0 comments on commit 0d5b165

Please sign in to comment.