diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb index 1509a8d32d67c5..d1d1f57d55b0bb 100644 --- a/bootstraptest/test_method.rb +++ b/bootstraptest/test_method.rb @@ -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{ diff --git a/parse.y b/parse.y index e8935b6988a6f5..a9db3d4e6eb181 100644 --- a/parse.y +++ b/parse.y @@ -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); } @@ -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); diff --git a/test/prism/fixtures/arrays.txt b/test/prism/fixtures/arrays.txt index 6cb0c25e608f46..63c490e5f8a4d2 100644 --- a/test/prism/fixtures/arrays.txt +++ b/test/prism/fixtures/arrays.txt @@ -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 diff --git a/test/prism/snapshots/arrays.txt b/test/prism/snapshots/arrays.txt index a2392f37e26113..2c26c5b556f603 100644 --- a/test/prism/snapshots/arrays.txt +++ b/test/prism/snapshots/arrays.txt @@ -2,7 +2,7 @@ ├── locals: [] └── statements: @ StatementsNode (location: (1,0)-(142,32)) - └── body: (length: 56) + └── body: (length: 50) ├── @ ArrayNode (location: (1,0)-(1,4)) │ ├── flags: contains_splat │ ├── elements: (length: 1) @@ -1360,332 +1360,6 @@ │ @ IntegerNode (location: (114,17)-(114,18)) │ ├── flags: decimal │ └── value: 1 - ├── @ IndexOperatorWriteNode (location: (116,0)-(116,19)) - │ ├── flags: ∅ - │ ├── receiver: - │ │ @ CallNode (location: (116,0)-(116,3)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :foo - │ │ ├── message_loc: (116,0)-(116,3) = "foo" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── call_operator_loc: ∅ - │ ├── opening_loc: (116,3)-(116,4) = "[" - │ ├── arguments: - │ │ @ ArgumentsNode (location: (116,4)-(116,7)) - │ │ ├── flags: ∅ - │ │ └── arguments: (length: 1) - │ │ └── @ CallNode (location: (116,4)-(116,7)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (116,4)-(116,7) = "bar" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── closing_loc: (116,13)-(116,14) = "]" - │ ├── block: - │ │ @ BlockArgumentNode (location: (116,9)-(116,13)) - │ │ ├── expression: - │ │ │ @ CallNode (location: (116,10)-(116,13)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :baz - │ │ │ ├── message_loc: (116,10)-(116,13) = "baz" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ └── operator_loc: (116,9)-(116,10) = "&" - │ ├── operator: :+ - │ ├── operator_loc: (116,15)-(116,17) = "+=" - │ └── value: - │ @ IntegerNode (location: (116,18)-(116,19)) - │ ├── flags: decimal - │ └── value: 1 - ├── @ IndexOrWriteNode (location: (118,0)-(118,20)) - │ ├── flags: ∅ - │ ├── receiver: - │ │ @ CallNode (location: (118,0)-(118,3)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :foo - │ │ ├── message_loc: (118,0)-(118,3) = "foo" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── call_operator_loc: ∅ - │ ├── opening_loc: (118,3)-(118,4) = "[" - │ ├── arguments: - │ │ @ ArgumentsNode (location: (118,4)-(118,7)) - │ │ ├── flags: ∅ - │ │ └── arguments: (length: 1) - │ │ └── @ CallNode (location: (118,4)-(118,7)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (118,4)-(118,7) = "bar" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── closing_loc: (118,13)-(118,14) = "]" - │ ├── block: - │ │ @ BlockArgumentNode (location: (118,9)-(118,13)) - │ │ ├── expression: - │ │ │ @ CallNode (location: (118,10)-(118,13)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :baz - │ │ │ ├── message_loc: (118,10)-(118,13) = "baz" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ └── operator_loc: (118,9)-(118,10) = "&" - │ ├── operator_loc: (118,15)-(118,18) = "||=" - │ └── value: - │ @ IntegerNode (location: (118,19)-(118,20)) - │ ├── flags: decimal - │ └── value: 1 - ├── @ IndexAndWriteNode (location: (120,0)-(120,20)) - │ ├── flags: ∅ - │ ├── receiver: - │ │ @ CallNode (location: (120,0)-(120,3)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :foo - │ │ ├── message_loc: (120,0)-(120,3) = "foo" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── call_operator_loc: ∅ - │ ├── opening_loc: (120,3)-(120,4) = "[" - │ ├── arguments: - │ │ @ ArgumentsNode (location: (120,4)-(120,7)) - │ │ ├── flags: ∅ - │ │ └── arguments: (length: 1) - │ │ └── @ CallNode (location: (120,4)-(120,7)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (120,4)-(120,7) = "bar" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── closing_loc: (120,13)-(120,14) = "]" - │ ├── block: - │ │ @ BlockArgumentNode (location: (120,9)-(120,13)) - │ │ ├── expression: - │ │ │ @ CallNode (location: (120,10)-(120,13)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :baz - │ │ │ ├── message_loc: (120,10)-(120,13) = "baz" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ └── operator_loc: (120,9)-(120,10) = "&" - │ ├── operator_loc: (120,15)-(120,18) = "&&=" - │ └── value: - │ @ IntegerNode (location: (120,19)-(120,20)) - │ ├── flags: decimal - │ └── value: 1 - ├── @ IndexOperatorWriteNode (location: (122,0)-(122,23)) - │ ├── flags: ∅ - │ ├── receiver: - │ │ @ CallNode (location: (122,0)-(122,7)) - │ │ ├── flags: ∅ - │ │ ├── receiver: - │ │ │ @ CallNode (location: (122,0)-(122,3)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :foo - │ │ │ ├── message_loc: (122,0)-(122,3) = "foo" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ ├── call_operator_loc: (122,3)-(122,4) = "." - │ │ ├── name: :foo - │ │ ├── message_loc: (122,4)-(122,7) = "foo" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── call_operator_loc: ∅ - │ ├── opening_loc: (122,7)-(122,8) = "[" - │ ├── arguments: - │ │ @ ArgumentsNode (location: (122,8)-(122,11)) - │ │ ├── flags: ∅ - │ │ └── arguments: (length: 1) - │ │ └── @ CallNode (location: (122,8)-(122,11)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (122,8)-(122,11) = "bar" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── closing_loc: (122,17)-(122,18) = "]" - │ ├── block: - │ │ @ BlockArgumentNode (location: (122,13)-(122,17)) - │ │ ├── expression: - │ │ │ @ CallNode (location: (122,14)-(122,17)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :baz - │ │ │ ├── message_loc: (122,14)-(122,17) = "baz" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ └── operator_loc: (122,13)-(122,14) = "&" - │ ├── operator: :+ - │ ├── operator_loc: (122,19)-(122,21) = "+=" - │ └── value: - │ @ IntegerNode (location: (122,22)-(122,23)) - │ ├── flags: decimal - │ └── value: 1 - ├── @ IndexOrWriteNode (location: (124,0)-(124,24)) - │ ├── flags: ∅ - │ ├── receiver: - │ │ @ CallNode (location: (124,0)-(124,7)) - │ │ ├── flags: ∅ - │ │ ├── receiver: - │ │ │ @ CallNode (location: (124,0)-(124,3)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :foo - │ │ │ ├── message_loc: (124,0)-(124,3) = "foo" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ ├── call_operator_loc: (124,3)-(124,4) = "." - │ │ ├── name: :foo - │ │ ├── message_loc: (124,4)-(124,7) = "foo" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── call_operator_loc: ∅ - │ ├── opening_loc: (124,7)-(124,8) = "[" - │ ├── arguments: - │ │ @ ArgumentsNode (location: (124,8)-(124,11)) - │ │ ├── flags: ∅ - │ │ └── arguments: (length: 1) - │ │ └── @ CallNode (location: (124,8)-(124,11)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (124,8)-(124,11) = "bar" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── closing_loc: (124,17)-(124,18) = "]" - │ ├── block: - │ │ @ BlockArgumentNode (location: (124,13)-(124,17)) - │ │ ├── expression: - │ │ │ @ CallNode (location: (124,14)-(124,17)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :baz - │ │ │ ├── message_loc: (124,14)-(124,17) = "baz" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ └── operator_loc: (124,13)-(124,14) = "&" - │ ├── operator_loc: (124,19)-(124,22) = "||=" - │ └── value: - │ @ IntegerNode (location: (124,23)-(124,24)) - │ ├── flags: decimal - │ └── value: 1 - ├── @ IndexAndWriteNode (location: (126,0)-(126,24)) - │ ├── flags: ∅ - │ ├── receiver: - │ │ @ CallNode (location: (126,0)-(126,7)) - │ │ ├── flags: ∅ - │ │ ├── receiver: - │ │ │ @ CallNode (location: (126,0)-(126,3)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :foo - │ │ │ ├── message_loc: (126,0)-(126,3) = "foo" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ ├── call_operator_loc: (126,3)-(126,4) = "." - │ │ ├── name: :foo - │ │ ├── message_loc: (126,4)-(126,7) = "foo" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── call_operator_loc: ∅ - │ ├── opening_loc: (126,7)-(126,8) = "[" - │ ├── arguments: - │ │ @ ArgumentsNode (location: (126,8)-(126,11)) - │ │ ├── flags: ∅ - │ │ └── arguments: (length: 1) - │ │ └── @ CallNode (location: (126,8)-(126,11)) - │ │ ├── flags: variable_call, ignore_visibility - │ │ ├── receiver: ∅ - │ │ ├── call_operator_loc: ∅ - │ │ ├── name: :bar - │ │ ├── message_loc: (126,8)-(126,11) = "bar" - │ │ ├── opening_loc: ∅ - │ │ ├── arguments: ∅ - │ │ ├── closing_loc: ∅ - │ │ └── block: ∅ - │ ├── closing_loc: (126,17)-(126,18) = "]" - │ ├── block: - │ │ @ BlockArgumentNode (location: (126,13)-(126,17)) - │ │ ├── expression: - │ │ │ @ CallNode (location: (126,14)-(126,17)) - │ │ │ ├── flags: variable_call, ignore_visibility - │ │ │ ├── receiver: ∅ - │ │ │ ├── call_operator_loc: ∅ - │ │ │ ├── name: :baz - │ │ │ ├── message_loc: (126,14)-(126,17) = "baz" - │ │ │ ├── opening_loc: ∅ - │ │ │ ├── arguments: ∅ - │ │ │ ├── closing_loc: ∅ - │ │ │ └── block: ∅ - │ │ └── operator_loc: (126,13)-(126,14) = "&" - │ ├── operator_loc: (126,19)-(126,22) = "&&=" - │ └── value: - │ @ IntegerNode (location: (126,23)-(126,24)) - │ ├── flags: decimal - │ └── value: 1 ├── @ DefNode (location: (128,0)-(128,19)) │ ├── name: :f │ ├── name_loc: (128,4)-(128,5) = "f" diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb index 09146efa41de96..d5fe9ce320d7a8 100644 --- a/test/ruby/test_call.rb +++ b/test/ruby/test_call.rb @@ -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 @@ -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 @@ -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 diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 65f1d96f97ac8c..8af9f1ade0d593 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -362,110 +362,6 @@ def test_GlobalVariableWriteNode assert_prism_eval("$pit = 1") end - def test_IndexAndWriteNode - assert_prism_eval("[0][0] &&= 1") - assert_prism_eval("[nil][0] &&= 1") - - # Testing `[]` with a block passed in - assert_prism_eval(<<-CODE) - class CustomHash < Hash - def []=(key, value, &block) - block ? super(block.call(key), value) : super(key, value) - end - end - - hash = CustomHash.new - - # Call the custom method with a block that modifies - # the key before assignment - hash["KEY"] = "test" - hash["key", &(Proc.new { _1.upcase })] &&= "value" - hash - CODE - - # Test with keyword arguments - assert_prism_eval(<<~RUBY) - h = Object.new - def h.[](**b) = 0 - def h.[]=(*a, **b); end - - h[foo: 1] &&= 2 - RUBY - - # Test with keyword splat - assert_prism_eval(<<~RUBY) - h = Object.new - def h.[](**b) = 1 - def h.[]=(*a, **b); end - - h[**{}] &&= 2 - RUBY - end - - def test_IndexOrWriteNode - assert_prism_eval("[0][0] ||= 1") - assert_prism_eval("[nil][0] ||= 1") - - # Testing `[]` with a block passed in - assert_prism_eval(<<-CODE) - class CustomHash < Hash - def []=(key, value, &block) - super(block.call(key), value) - end - end - - hash = CustomHash.new - - # Call the custom method with a block that modifies - # the key before assignment - hash["key", &(Proc.new { _1.upcase })] ||= "value" - hash - CODE - - # Test with keyword arguments - assert_prism_eval(<<~RUBY) - h = Object.new - def h.[](**b) = 0 - def h.[]=(*a, **b); end - - h[foo: 1] ||= 2 - RUBY - - # Test with keyword splat - assert_prism_eval(<<~RUBY) - h = Object.new - def h.[](**b) = nil - def h.[]=(*a, **b); end - - h[**{}] ||= 2 - RUBY - end - - def test_IndexOperatorWriteNode - assert_prism_eval("[0][0] += 1") - - # Testing `[]` with a block passed in - assert_prism_eval(<<-CODE) - class CustomHash < Hash - def [](key, &block) - block ? super(block.call(key)) : super(key) - end - - def []=(key, value, &block) - block ? super(block.call(key), value) : super(key, value) - end - end - - hash = CustomHash.new - - # Call the custom method with a block that modifies - # the key before assignment - hash["KEY"] = "test" - hash["key", &(Proc.new { _1.upcase })] &&= "value" - hash - CODE - end - def test_InstanceVariableAndWriteNode assert_prism_eval("@pit = 0; @pit &&= 1") end diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index 051fac274f60e3..a4ca08ec277c92 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -507,16 +507,16 @@ def t.[]=(_, _) end def t.dummy(_) end - eval <<-END, nil, __FILE__, __LINE__+1 + + assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /block arg given in index/) + begin; t[42, &blk] ||= 42 - END - assert_equal([:aref, :aset], a) - a.clear - eval <<-END, nil, __FILE__, __LINE__+1 - t[42, &blk] ||= t.dummy 42 # command_asgn test - END - assert_equal([:aref, :aset], a) - blk + end; + + assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /block arg given in index/) + begin; + t[42, &blk] ||= t.dummy 42 # command_asgn test + end; end def test_backquote