From 13cd963500106b366c8df9eec5c1b6815e93f07f Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Tue, 21 Nov 2023 09:02:31 -0800 Subject: Prevent modification of splat array inside setup_parameters_complex For the following: ``` def f(*a); a end p f(*a, kw: 3) ``` `setup_parameters_complex` pushes `{kw: 3}` onto `a`. This worked fine back when `concatarray true` was used and `a` was already a copy. It does not work correctly with the optimization to switch to `concatarray false`. This duplicates the array on the callee side in such a case. This affects cases when passing a regular splat and a keyword splat (or literal keywords) in a method call, where the method does not accept keywords. This allocation could probably be avoided, but doing so would make `setup_parameters_complex` more complicated. --- test/ruby/test_call.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test/ruby') diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb index a272d9d0dd..67a94ed7af 100644 --- a/test/ruby/test_call.rb +++ b/test/ruby/test_call.rb @@ -100,6 +100,12 @@ class TestCall < Test::Unit::TestCase } end + def test_frozen_splat_and_keywords + a = [1, 2].freeze + def self.f(*a); a end + assert_equal([1, 2, {kw: 3}], f(*a, kw: 3)) + end + def test_call_bmethod_proc pr = proc{|sym| sym} define_singleton_method(:a, &pr) -- cgit v1.2.3