[前][次][番号順一覧][スレッド一覧]

ruby-changes:65948

From: Alan <ko1@a...>
Date: Sat, 24 Apr 2021 11:17:32 +0900 (JST)
Subject: [ruby-changes:65948] dee58d7ae7 (master): Add back checks for empty kw splat with tests (#4405)

https://git.ruby-lang.org/ruby.git/commit/?id=dee58d7ae7

From dee58d7ae7b75971f349f2217007fdf45d1ea23d Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Fri, 23 Apr 2021 22:17:20 -0400
Subject: Add back checks for empty kw splat with tests (#4405)

This reverts commit a224ce8150f2bc687cf79eb415c931d87a4cd247.
Turns out the checks are needed to handle splatting an array with an
empty ruby2 keywords hash.
---
 test/ruby/test_keyword.rb | 20 ++++++++++++++++++++
 vm_insnhelper.c           |  2 ++
 2 files changed, 22 insertions(+)

diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 0bdcb79..c8191a7 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -2411,6 +2411,13 @@ class TestKeywordArguments < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L2411
         args
       end
 
+      def empty_method
+      end
+
+      def opt(arg = :opt)
+        arg
+      end
+
       ruby2_keywords def foo_dbar(*args)
         dbar(*args)
       end
@@ -2419,6 +2426,16 @@ class TestKeywordArguments < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L2426
         dbaz(*args)
       end
 
+      ruby2_keywords def clear_last_empty_method(*args)
+        args.last.clear
+        empty_method(*args)
+      end
+
+      ruby2_keywords def clear_last_opt(*args)
+        args.last.clear
+        opt(*args)
+      end
+
       define_method(:dbar) do |*args, **kw|
         [args, kw]
       end
@@ -2653,6 +2670,9 @@ class TestKeywordArguments < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L2670
     assert_equal([[1, h1], {}], o.foo(:pass_bar, 1, :a=>1))
     assert_equal([[1, h1], {}], o.foo(:pass_cfunc, 1, :a=>1))
 
+    assert_equal(:opt, o.clear_last_opt(a: 1))
+    assert_nothing_raised(ArgumentError) { o.clear_last_empty_method(a: 1) }
+
     assert_warn(/Skipping set of ruby2_keywords flag for bar \(method accepts keywords or method does not accept argument splat\)/) do
       assert_nil(c.send(:ruby2_keywords, :bar))
     end
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 7c715c9..840bd49 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -2412,6 +2412,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2412
         if (LIKELY(rb_simple_iseq_p(iseq))) {
             rb_control_frame_t *cfp = ec->cfp;
             CALLER_SETUP_ARG(cfp, calling, ci);
+            CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
 
             if (calling->argc != iseq->body->param.lead_num) {
                 argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
@@ -2425,6 +2426,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2426
         else if (rb_iseq_only_optparam_p(iseq)) {
             rb_control_frame_t *cfp = ec->cfp;
             CALLER_SETUP_ARG(cfp, calling, ci);
+            CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
 
             const int lead_num = iseq->body->param.lead_num;
             const int opt_num = iseq->body->param.opt_num;
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]