From 4c3140d60f6f94504842a4d0c0d79752a87aec8d Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 15 Jul 2021 21:25:43 +0900 Subject: [PATCH] Add keyrest to ruby2_keywords parameters [Bug #18011] --- iseq.c | 13 +++++++++++-- proc.c | 7 ++++++- test/ruby/test_method.rb | 4 ++-- test/ruby/test_syntax.rb | 3 ++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/iseq.c b/iseq.c index 47bc108d3eb3e3..b08f1bb497f99b 100644 --- a/iseq.c +++ b/iseq.c @@ -3116,9 +3116,18 @@ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc) rb_ary_push(args, a); } } - if (body->param.flags.has_kwrest) { + if (body->param.flags.has_kwrest || body->param.flags.ruby2_keywords) { + ID param; CONST_ID(keyrest, "keyrest"); - rb_ary_push(args, PARAM(keyword->rest_start, keyrest)); + PARAM_TYPE(keyrest); + if (body->param.flags.has_kwrest && + rb_id2str(param = PARAM_ID(keyword->rest_start))) { + rb_ary_push(a, ID2SYM(param)); + } + else if (body->param.flags.ruby2_keywords) { + rb_ary_push(a, ID2SYM(idPow)); + } + rb_ary_push(args, a); } if (body->param.flags.has_block) { CONST_ID(block, "block"); diff --git a/proc.c b/proc.c index 823d806ffd77fb..d4236d0061f401 100644 --- a/proc.c +++ b/proc.c @@ -3097,7 +3097,12 @@ method_inspect(VALUE method) } } else if (kind == keyrest) { - rb_str_catf(str, "**%"PRIsVALUE, name); + if (name != ID2SYM(idPow)) { + rb_str_catf(str, "**%"PRIsVALUE, name); + } + else if (i > 0) { + rb_str_set_len(str, RSTRING_LEN(str) - 2); + } } else if (kind == block) { if (name == ID2SYM('&')) { diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index 0bd5dc63dddb05..daf0ec73ca1ff6 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -578,7 +578,7 @@ def test_bound_parameters assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyreq, :e], [:key, :f], [:keyrest, :o]], method(:mk8).parameters) assert_equal([[:nokey]], method(:mnk).parameters) # pending - assert_equal([[:rest, :*], [:block, :&]], method(:mf).parameters) + assert_equal([[:rest, :*], [:keyrest, :**], [:block, :&]], method(:mf).parameters) end def test_unbound_parameters @@ -604,7 +604,7 @@ def test_unbound_parameters assert_equal([[:req, :a], [:opt, :b], [:rest, :c], [:req, :d], [:keyreq, :e], [:key, :f], [:keyrest, :o]], self.class.instance_method(:mk8).parameters) assert_equal([[:nokey]], self.class.instance_method(:mnk).parameters) # pending - assert_equal([[:rest, :*], [:block, :&]], self.class.instance_method(:mf).parameters) + assert_equal([[:rest, :*], [:keyrest, :**], [:block, :&]], self.class.instance_method(:mf).parameters) end def test_bmethod_bound_parameters diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index 31db1320fc76b9..8aa169ac0c76dc 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -1638,7 +1638,8 @@ def obj3.bar(*args, &block) assert_equal(-1, obj.method(:foo).arity) parameters = obj.method(:foo).parameters assert_equal(:rest, parameters.dig(0, 0)) - assert_equal(:block, parameters.dig(1, 0)) + assert_equal(:keyrest, parameters.dig(1, 0)) + assert_equal(:block, parameters.dig(2, 0)) end end