diff options
author | Jeremy Evans <code@jeremyevans.net> | 2019-10-24 12:36:49 -0700 |
---|---|---|
committer | Jeremy Evans <code@jeremyevans.net> | 2019-10-24 17:25:43 -0700 |
commit | fb15e79403181098c969b4a8b7e4dd69f820955d (patch) | |
tree | c4e8295f873ab6676d500633a0c0cc617d281659 | |
parent | 5040eea959300ecb183d79f9539151239c281aa6 (diff) | |
download | ruby-fb15e79403181098c969b4a8b7e4dd69f820955d.tar.gz |
Handle case where ruby2_keywords method splats to ruby2_keywords method
Previously, the keyword hash was duped (which results in a regular
hash), but the dup was not marked as a keyword hash, causing the
hash not to be marked as keyword hash even though it should be.
-rw-r--r-- | test/ruby/test_keyword.rb | 26 | ||||
-rw-r--r-- | vm_args.c | 3 |
2 files changed, 29 insertions, 0 deletions
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb index 0f67c28963..28a80fd198 100644 --- a/test/ruby/test_keyword.rb +++ b/test/ruby/test_keyword.rb @@ -2649,6 +2649,14 @@ class TestKeywordArguments < Test::Unit::TestCase baz(*args) end + ruby2_keywords def foo_foo_bar(meth, *args) + foo_bar(meth, *args) + end + + ruby2_keywords def foo_foo_baz(meth, *args) + foo_baz(meth, *args) + end + ruby2_keywords def foo_mod(meth, *args) args << 1 send(meth, *args) @@ -2761,6 +2769,12 @@ class TestKeywordArguments < Test::Unit::TestCase assert_equal([1, h1], o.store_foo(:baz, 1, :a=>1)) assert_equal([[1], h1], o.foo_bar(1, :a=>1)) assert_equal([1, h1], o.foo_baz(1, :a=>1)) + assert_equal([[1], h1], o.foo(:foo, :bar, 1, :a=>1)) + assert_equal([1, h1], o.foo(:foo, :baz, 1, :a=>1)) + assert_equal([[1], h1], o.foo(:foo_bar, 1, :a=>1)) + assert_equal([1, h1], o.foo(:foo_baz, 1, :a=>1)) + assert_equal([[1], h1], o.foo_foo_bar(1, :a=>1)) + assert_equal([1, h1], o.foo_foo_baz(1, :a=>1)) assert_equal([[1], h1], o.foo(:bar, 1, **h1)) assert_equal([1, h1], o.foo(:baz, 1, **h1)) @@ -2770,6 +2784,12 @@ class TestKeywordArguments < Test::Unit::TestCase assert_equal([1, h1], o.store_foo(:baz, 1, **h1)) assert_equal([[1], h1], o.foo_bar(1, **h1)) assert_equal([1, h1], o.foo_baz(1, **h1)) + assert_equal([[1], h1], o.foo(:foo, :bar, 1, **h1)) + assert_equal([1, h1], o.foo(:foo, :baz, 1, **h1)) + assert_equal([[1], h1], o.foo(:foo_bar, 1, **h1)) + assert_equal([1, h1], o.foo(:foo_baz, 1, **h1)) + assert_equal([[1], h1], o.foo_foo_bar(1, **h1)) + assert_equal([1, h1], o.foo_foo_baz(1, **h1)) assert_equal([[h1], {}], o.foo(:bar, h1, **{})) assert_equal([h1], o.foo(:baz, h1, **{})) @@ -2779,6 +2799,12 @@ class TestKeywordArguments < Test::Unit::TestCase assert_equal([h1], o.store_foo(:baz, h1, **{})) assert_equal([[h1], {}], o.foo_bar(h1, **{})) assert_equal([h1], o.foo_baz(h1, **{})) + assert_equal([[h1], {}], o.foo(:foo, :bar, h1, **{})) + assert_equal([h1], o.foo(:foo, :baz, h1, **{})) + assert_equal([[h1], {}], o.foo(:foo_bar, h1, **{})) + assert_equal([h1], o.foo(:foo_baz, h1, **{})) + assert_equal([[h1], {}], o.foo_foo_bar(h1, **{})) + assert_equal([h1], o.foo_foo_baz(h1, **{})) assert_warn(/The last argument is used as the keyword parameter.* for `bar'/m) do assert_equal([[1], h1], o.foo(:bar, 1, h1)) @@ -740,6 +740,9 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co rest_last = rb_hash_dup(rest_last); RARRAY_ASET(args->rest, len - 1, rest_last); kw_flag |= VM_CALL_KW_SPLAT; + if (iseq->body->param.flags.ruby2_keywords) { + remove_empty_keyword_hash = 0; + } } else { rest_last = 0; |