diff --git a/prism_compile.c b/prism_compile.c index 9594be70659592..cbae85b9f40cc5 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 835b3b819b8c0b..71155979036e40 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -1484,6 +1484,13 @@ def foo.[]=(k,v); 42; end 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")