aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--compile.c2
-rw-r--r--iseq.c6
-rw-r--r--parse.y7
-rw-r--r--test/ruby/test_keyword.rb9
5 files changed, 33 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 6c3c0b00f8..8bdf25b6e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Wed Dec 25 22:44:14 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * compile.c (iseq_set_arguments): set arg_keyword_check from
+ nd_cflag, which is set by parser. internal ID is used for
+ unnamed keyword rest argument, which should be separated from no
+ keyword check.
+
+ * iseq.c (rb_iseq_parameters): if no keyword check, keyword rest is
+ present.
+
+ * parse.y (new_args_tail_gen): set keywords check to nd_cflag, which
+ equals to that keyword rest is not present.
+
Wed Dec 25 22:32:19 2013 Zachary Scott <e@zzak.io>
* lib/abbrev.rb: [DOC] rdoc format patch by Giorgos Tsiftsis [Bug #9146]
diff --git a/compile.c b/compile.c
index 48479338c9..43a0a5d9da 100644
--- a/compile.c
+++ b/compile.c
@@ -1203,7 +1203,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
node = node->nd_next;
i += 1;
}
- iseq->arg_keyword_check = (args->kw_rest_arg->nd_vid & ID_SCOPE_MASK) == ID_JUNK;
+ iseq->arg_keyword_check = args->kw_rest_arg->nd_cflag;
iseq->arg_keywords = i;
iseq->arg_keyword_required = r;
iseq->arg_keyword_table = ALLOC_N(ID, i);
diff --git a/iseq.c b/iseq.c
index 1b33c559e3..a829089ea4 100644
--- a/iseq.c
+++ b/iseq.c
@@ -2015,8 +2015,10 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
}
rb_ary_push(args, a);
}
- CONST_ID(keyrest, "keyrest");
- rb_ary_push(args, PARAM(iseq->arg_keyword, keyrest));
+ if (!iseq->arg_keyword_check) {
+ CONST_ID(keyrest, "keyrest");
+ rb_ary_push(args, PARAM(iseq->arg_keyword, keyrest));
+ }
}
if (iseq->arg_block != -1) {
CONST_ID(block, "block");
diff --git a/parse.y b/parse.y
index d04cf45612..a55f8d7a5c 100644
--- a/parse.y
+++ b/parse.y
@@ -9485,6 +9485,7 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
struct rb_args_info *args;
NODE *kw_rest_arg = 0;
NODE *node;
+ int check = 0;
args = ALLOC(struct rb_args_info);
MEMZERO(args, struct rb_args_info, 1);
@@ -9492,10 +9493,14 @@ new_args_tail_gen(struct parser_params *parser, NODE *k, ID kr, ID b)
args->block_arg = b;
args->kw_args = k;
- if (k && !kr) kr = internal_id();
+ if (k && !kr) {
+ check = 1;
+ kr = internal_id();
+ }
if (kr) {
arg_var(kr);
kw_rest_arg = NEW_DVAR(kr);
+ kw_rest_arg->nd_cflag = check;
}
args->kw_rest_arg = kw_rest_arg;
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index d636d75a92..625146b0ba 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -117,6 +117,15 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([1, 2, [3, 4], 5, :key, {str: "bar"}, nil], f9(1, 2, 3, 4, 5, str: "bar"))
end
+ def f10(a: 1, **)
+ a
+ end
+
+ def test_f10
+ assert_equal(42, f10(a: 42))
+ assert_equal(1, f10(b: 42))
+ end
+
def test_method_parameters
assert_equal([[:key, :str], [:key, :num]], method(:f1).parameters);
assert_equal([[:req, :x], [:key, :str], [:key, :num]], method(:f2).parameters);