ruby-changes:32341
From: nobu <ko1@a...>
Date: Wed, 25 Dec 2013 22:44:27 +0900 (JST)
Subject: [ruby-changes:32341] nobu:r44420 (trunk): compile.c: unnamed keyword rest check
nobu 2013-12-25 22:44:18 +0900 (Wed, 25 Dec 2013) New Revision: 44420 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44420 Log: compile.c: unnamed keyword rest check * 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. Modified files: trunk/ChangeLog trunk/compile.c trunk/iseq.c trunk/parse.y trunk/test/ruby/test_keyword.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 44419) +++ ChangeLog (revision 44420) @@ -1,3 +1,16 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Dec 25 22:44:14 2013 Nobuyoshi Nakada <nobu@r...> + + * 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@z...> * lib/abbrev.rb: [DOC] rdoc format patch by Giorgos Tsiftsis [Bug #9146] Index: iseq.c =================================================================== --- iseq.c (revision 44419) +++ iseq.c (revision 44420) @@ -2015,8 +2015,10 @@ rb_iseq_parameters(const rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/iseq.c#L2015 } 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"); Index: compile.c =================================================================== --- compile.c (revision 44419) +++ compile.c (revision 44420) @@ -1203,7 +1203,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK https://github.com/ruby/ruby/blob/trunk/compile.c#L1203 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); Index: parse.y =================================================================== --- parse.y (revision 44419) +++ parse.y (revision 44420) @@ -9485,6 +9485,7 @@ new_args_tail_gen(struct parser_params * https://github.com/ruby/ruby/blob/trunk/parse.y#L9485 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 * https://github.com/ruby/ruby/blob/trunk/parse.y#L9493 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; Index: test/ruby/test_keyword.rb =================================================================== --- test/ruby/test_keyword.rb (revision 44419) +++ test/ruby/test_keyword.rb (revision 44420) @@ -117,6 +117,15 @@ class TestKeywordArguments < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L117 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); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/