From 3354aacb73c65420a10cb41c0696e62dd1ba279b Mon Sep 17 00:00:00 2001 From: nagachika Date: Sun, 23 Jul 2023 12:01:21 +0900 Subject: [PATCH] merge revision(s) 3874381c4483ba7794ac2abf157e265546f9bfa7: [Backport #19759] Fix autosplat conditions to handle ruby2_keywords case Autosplat should not occur if there are two arguments but second argument is an array containing a ruby2_keywords splat. Only autosplat if a single argument to be yielded to the block, and there is no splatted flagged keyword hash passed. Fixes [Bug #19759] --- test/ruby/test_proc.rb | 26 ++++++++++++++++++++++++++ vm_args.c | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) --- test/ruby/test_proc.rb | 26 ++++++++++++++++++++++++++ version.h | 2 +- vm_args.c | 3 ++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb index 05c6e03aac..2b3590d4d0 100644 --- a/test/ruby/test_proc.rb +++ b/test/ruby/test_proc.rb @@ -1321,6 +1321,32 @@ class TestProc < Test::Unit::TestCase assert_empty(pr.parameters.map{|_,n|n}.compact) end + def test_proc_autosplat_with_multiple_args_with_ruby2_keywords_splat_bug_19759 + def self.yielder_ab(splat) + yield([:a, :b], *splat) + end + + res = yielder_ab([[:aa, :bb], Hash.ruby2_keywords_hash({k: :k})]) do |a, b, k:| + [a, b, k] + end + assert_equal([[:a, :b], [:aa, :bb], :k], res) + + def self.yielder(splat) + yield(*splat) + end + res = yielder([ [:a, :b] ]){|a, b, **| [a, b]} + assert_equal([:a, :b], res) + + res = yielder([ [:a, :b], Hash.ruby2_keywords_hash({}) ]){|a, b, **| [a, b]} + assert_equal([[:a, :b], nil], res) + + res = yielder([ [:a, :b], Hash.ruby2_keywords_hash({c: 1}) ]){|a, b, **| [a, b]} + assert_equal([[:a, :b], nil], res) + + res = yielder([ [:a, :b], Hash.ruby2_keywords_hash({}) ]){|a, b, **nil| [a, b]} + assert_equal([[:a, :b], nil], res) + end + def test_parameters_lambda assert_equal([], proc {}.parameters(lambda: true)) assert_equal([], proc {||}.parameters(lambda: true)) diff --git a/version.h b/version.h index 11df7d659b..5532e4cf36 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 2 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 103 +#define RUBY_PATCHLEVEL 104 #include "ruby/version.h" #include "ruby/internal/abi.h" diff --git a/vm_args.c b/vm_args.c index 0197109b03..498ce3d97e 100644 --- a/vm_args.c +++ b/vm_args.c @@ -605,8 +605,9 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co case arg_setup_method: break; /* do nothing special */ case arg_setup_block: - if (given_argc == (NIL_P(keyword_hash) ? 1 : 2) && + if (given_argc == 1 && allow_autosplat && + !splat_flagged_keyword_hash && (min_argc > 0 || ISEQ_BODY(iseq)->param.opt_num > 1) && !ISEQ_BODY(iseq)->param.flags.ambiguous_param0 && !((ISEQ_BODY(iseq)->param.flags.has_kw ||