diff --git a/prism_compile.c b/prism_compile.c index 40d2eb9806..4d139a57b3 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -952,6 +952,17 @@ pm_compile_index_write_nodes_add_send(bool popped, LINK_ANCHOR *const ret, rb_is } ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, argc, INT2FIX(flag)); } + else if (flag & VM_CALL_KW_SPLAT) { + if (block_offset > 0) { + ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(2)); + PM_SWAP; + ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(3)); + PM_POP; + } + + ADD_INSN(ret, &dummy_line_node, swap); + ADD_SEND_R(ret, &dummy_line_node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), keywords); + } else if (keywords && keywords->keyword_len) { ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keywords->keyword_len + block_offset + 1)); ADD_INSN1(ret, &dummy_line_node, opt_reverse, INT2FIX(keywords->keyword_len + block_offset + 0)); diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 0998c8fa5d..8f42fb5851 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -394,6 +394,15 @@ module Prism 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 @@ -415,6 +424,15 @@ module Prism hash["key", &(Proc.new { _1.upcase })] ||= "value" hash CODE + + # 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