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

ruby-changes:55049

From: mame <ko1@a...>
Date: Thu, 14 Mar 2019 18:05:01 +0900 (JST)
Subject: [ruby-changes:55049] mame:r67256 (trunk): compile.c: fix the corner case of rest and keyword arguments

mame	2019-03-14 18:04:57 +0900 (Thu, 14 Mar 2019)

  New Revision: 67256

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=67256

  Log:
    compile.c: fix the corner case of rest and keyword arguments
    
    See https://bugs.ruby-lang.org/issues/10856#note-20 . [Bug #10856]

  Modified files:
    trunk/compile.c
    trunk/test/ruby/test_keyword.rb
Index: compile.c
===================================================================
--- compile.c	(revision 67255)
+++ compile.c	(revision 67256)
@@ -4773,6 +4773,22 @@ add_ensure_iseq(LINK_ANCHOR *const ret, https://github.com/ruby/ruby/blob/trunk/compile.c#L4773
     ADD_SEQ(ret, ensure);
 }
 
+static int
+check_keyword(const NODE *node)
+{
+    /* This check is essentially a code clone of compile_keyword_arg. */
+
+    if (nd_type(node) == NODE_ARRAY) {
+        while (node->nd_next) {
+            node = node->nd_next;
+        }
+        node = node->nd_head;
+    }
+
+    if (nd_type(node) == NODE_HASH && !node->nd_alen) return TRUE;
+    return FALSE;
+}
+
 static VALUE
 setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn,
                 int dup_rest, unsigned int *flag, struct rb_call_info_kw_arg **keywords)
@@ -4792,8 +4808,9 @@ setup_args_core(rb_iseq_t *iseq, LINK_AN https://github.com/ruby/ruby/blob/trunk/compile.c#L4808
             COMPILE(args, "args (cat: splat)", argn->nd_body);
             if (flag) {
                 *flag |= VM_CALL_ARGS_SPLAT;
-                if (nd_type(argn->nd_body) == NODE_HASH)
-                    /* bug: https://bugs.ruby-lang.org/issues/10856#change-77095 */
+                /* This is a dirty hack.  It traverses the AST twice.
+                 * In a long term, it should be fixed by a redesign of keyword arguments */
+                if (check_keyword(argn->nd_body))
                     *flag |= VM_CALL_KW_SPLAT;
             }
             if (nd_type(argn) == NODE_ARGSCAT) {
Index: test/ruby/test_keyword.rb
===================================================================
--- test/ruby/test_keyword.rb	(revision 67255)
+++ test/ruby/test_keyword.rb	(revision 67256)
@@ -518,6 +518,8 @@ class TestKeywordArguments < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L518
     assert_equal(:ok, m.f(**o), '[ruby-core:68124] [Bug #10856]')
     a = []
     assert_equal(:ok, m.f(*a, **o), '[ruby-core:83638] [Bug #10856]')
+    assert_equal(:OK, m.f1(*a, :OK, **o), '[ruby-core:91825] [Bug #10856]')
+    assert_equal({}, m.f1(*a, o), '[ruby-core:91825] [Bug #10856]')
 
     o = {a: 42}
     assert_warning(/splat keyword/, 'splat to mandatory') do

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

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