diff options
author | Peter Zhu <[email protected]> | 2024-01-11 12:27:50 -0500 |
---|---|---|
committer | Peter Zhu <[email protected]> | 2024-01-11 14:58:24 -0500 |
commit | 45dd8edf82d2648fed51b0e65f6fc1cf4473038d (patch) | |
tree | 619540f524d1ef751bfd375c35a64856421d080c | |
parent | f2149dc094a92bd1aa29622f9585247d491f7a08 (diff) |
[PRISM] Fix splat inside of aset
Fixes ruby/prism#2146.
-rw-r--r-- | prism_compile.c | 10 | ||||
-rw-r--r-- | test/ruby/test_compile_prism.rb | 7 |
2 files changed, 16 insertions, 1 deletions
diff --git a/prism_compile.c b/prism_compile.c index 9594be7065..cbae85b9f4 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -2645,9 +2645,17 @@ pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *c } if (pm_node->flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { - if (!popped) { + if (flags & VM_CALL_ARGS_SPLAT) { + ADD_INSN(ret, &dummy_line_node, dup); + ADD_INSN1(ret, &dummy_line_node, putobject, INT2FIX(-1)); + ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, INT2FIX(1), INT2FIX(0)); + ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(orig_argc + 2)); + ADD_INSN (ret, &dummy_line_node, pop); + } + else if (!popped) { ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(orig_argc + 1)); } + ADD_SEND_R(ret, &dummy_line_node, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg); PM_POP_UNLESS_POPPED; } diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 835b3b819b..7115597903 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -1484,6 +1484,13 @@ module Prism foo.[]=(1,2) CODE + # With splat inside of []= + assert_prism_eval(<<~RUBY) + obj = Object.new + def obj.[]=(a, b); 10; end + obj[*[1]] = 3 + RUBY + assert_prism_eval(<<-CODE) def self.prism_opt_var_trail_hash(a = nil, *b, c, **d); end prism_opt_var_trail_hash("a") |