diff options
| -rw-r--r-- | test/ruby/test_keyword.rb | 100 | ||||
| -rw-r--r-- | vm_insnhelper.c | 4 |
2 files changed, 79 insertions, 25 deletions
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb index 229f0b3871..71b72bd4ed 100644 --- a/test/ruby/test_keyword.rb +++ b/test/ruby/test_keyword.rb @@ -185,20 +185,42 @@ class TestKeywordArguments < Test::Unit::TestCase f = -> { true } assert_equal(true, f[**{}]) - assert_raise(ArgumentError) { f[**kw] } - assert_raise(ArgumentError) { f[**h] } - assert_raise(ArgumentError) { f[a: 1] } - assert_raise(ArgumentError) { f[**h2] } - assert_raise(ArgumentError) { f[**h3] } + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { f[**kw] } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { f[**h] } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { f[a: 1] } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { f[**h2] } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { f[**h3] } + end f = ->(a) { a } assert_raise(ArgumentError) { f[**{}] } - assert_equal(kw, f[**kw]) - assert_equal(h, f[**h]) - assert_equal(h, f[a: 1]) - assert_equal(h2, f[**h2]) - assert_equal(h3, f[**h3]) - assert_equal(h3, f[a: 1, **h2]) + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(kw, f[**kw]) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h, f[**h]) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h, f[a: 1]) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h2, f[**h2]) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h3, f[**h3]) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h3, f[a: 1, **h2]) + end f = ->(**x) { x } assert_equal(kw, f[**{}]) @@ -685,24 +707,48 @@ class TestKeywordArguments < Test::Unit::TestCase define_method(:m) { } end assert_nil(c.m(**{})) - assert_raise(ArgumentError) { c.m(**kw) } - assert_raise(ArgumentError) { c.m(**h) } - assert_raise(ArgumentError) { c.m(a: 1) } - assert_raise(ArgumentError) { c.m(**h2) } - assert_raise(ArgumentError) { c.m(**h3) } - assert_raise(ArgumentError) { c.m(a: 1, **h2) } + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { c.m(**kw) } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { c.m(**h) } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { c.m(a: 1) } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { c.m(**h2) } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { c.m(**h3) } + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_raise(ArgumentError) { c.m(a: 1, **h2) } + end c = Object.new class << c define_method(:m) {|arg| arg } end assert_raise(ArgumentError) { c.m(**{}) } - assert_equal(kw, c.m(**kw)) - assert_equal(h, c.m(**h)) - assert_equal(h, c.m(a: 1)) - assert_equal(h2, c.m(**h2)) - assert_equal(h3, c.m(**h3)) - assert_equal(h3, c.m(a: 1, **h2)) + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(kw, c.m(**kw)) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h, c.m(**h)) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h, c.m(a: 1)) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h2, c.m(**h2)) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h3, c.m(**h3)) + end + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal(h3, c.m(a: 1, **h2)) + end c = Object.new class << c @@ -1211,10 +1257,14 @@ class TestKeywordArguments < Test::Unit::TestCase o = Object.new def o.to_hash() { a: 1 } end - assert_equal({a: 1}, m1(**o) {|x| break x}, bug9898) + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal({a: 1}, m1(**o) {|x| break x}, bug9898) + end o2 = Object.new def o2.to_hash() { b: 2 } end - assert_equal({a: 1, b: 2}, m1(**o, **o2) {|x| break x}, bug9898) + assert_warn(/The keyword argument is passed as the last hash parameter/m) do + assert_equal({a: 1, b: 2}, m1(**o, **o2) {|x| break x}, bug9898) + end end def test_implicit_hash_conversion diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 92a9bc6c9a..baf93de742 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2929,6 +2929,10 @@ vm_callee_setup_block_arg(rb_execution_context_t *ec, struct rb_calling_info *ca CALLER_SETUP_ARG(cfp, calling, ci, 0); /* splat arg */ + if (calling->kw_splat) { + rb_warn_keyword_to_last_hash(calling, ci, iseq); + } + if (arg_setup_type == arg_setup_block && calling->argc == 1 && iseq->body->param.flags.has_lead && |
