diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-02-22 10:40:25 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2020-02-22 10:49:59 +0900 |
commit | 5b29ea0845c14092abd866ce0183c52635bade4c (patch) | |
tree | 1c01654c72d24c7fa499bb5b6f91fc3e55d6c84a | |
parent | 31748e69c84894ac8f042a67d1320db8593c9ce1 (diff) | |
download | ruby-5b29ea0845c14092abd866ce0183c52635bade4c.tar.gz |
Proc from Symbol needs a receiver
So its arity should be -2 instead of -1.
[Bug #16640]
https://bugs.ruby-lang.org/issues/16640#change-84337
-rw-r--r-- | proc.c | 3 | ||||
-rw-r--r-- | spec/ruby/core/symbol/to_proc_spec.rb | 10 | ||||
-rw-r--r-- | test/ruby/test_symbol.rb | 12 | ||||
-rw-r--r-- | vm_args.c | 2 |
4 files changed, 19 insertions, 8 deletions
@@ -1091,7 +1091,8 @@ rb_vm_block_min_max_arity(const struct rb_block *block, int *max) return ifunc->argc.min; } case block_type_symbol: - break; + *max = UNLIMITED_ARGUMENTS; + return 1; } *max = UNLIMITED_ARGUMENTS; return 0; diff --git a/spec/ruby/core/symbol/to_proc_spec.rb b/spec/ruby/core/symbol/to_proc_spec.rb index a58187de2e..27eb6970c4 100644 --- a/spec/ruby/core/symbol/to_proc_spec.rb +++ b/spec/ruby/core/symbol/to_proc_spec.rb @@ -12,18 +12,20 @@ describe "Symbol#to_proc" do :to_s.to_proc.call(obj).should == "Received #to_s" end - it "produces a proc with arity -1" do + expected_arity = ruby_version_is("2.8") {-2} || -1 + it "produces a proc with arity #{expected_arity}" do pr = :to_s.to_proc - pr.arity.should == -1 + pr.arity.should == expected_arity end it "raises an ArgumentError when calling #call on the Proc without receiver" do -> { :object_id.to_proc.call }.should raise_error(ArgumentError, "no receiver given") end - it "produces a proc that always returns [[:rest]] for #parameters" do + expected_parameters = ruby_version_is("2.8") {[[:req], [:rest]]} || [[:rest]] + it "produces a proc that always returns #{expected_parameters} for #parameters" do pr = :to_s.to_proc - pr.parameters.should == [[:rest]] + pr.parameters.should == expected_parameters end it "passes along the block passed to Proc#call" do diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb index 632acb3e3d..569b888f31 100644 --- a/test/ruby/test_symbol.rb +++ b/test/ruby/test_symbol.rb @@ -157,6 +157,10 @@ class TestSymbol < Test::Unit::TestCase assert_predicate(:itself.to_proc, :lambda?) end + def test_to_proc_arity + assert_equal(-2, :itself.to_proc.arity) + end + def test_to_proc_call_with_symbol_proc first = 1 bug11594 = "[ruby-core:71088] [Bug #11594] corrupted the first local variable" @@ -187,6 +191,10 @@ class TestSymbol < Test::Unit::TestCase assert_predicate(_test_to_proc_with_refinements_call(&:hoge), :lambda?) end + def test_to_proc_arity_with_refinements + assert_equal(-2, _test_to_proc_with_refinements_call(&:hoge).arity) + end + def self._test_to_proc_arg_with_refinements_call(&block) block.call TestToPRocArgWithRefinements.new end @@ -230,11 +238,11 @@ class TestSymbol < Test::Unit::TestCase begin; bug11845 = '[ruby-core:72381] [Bug #11845]' assert_nil(:class.to_proc.source_location, bug11845) - assert_equal([[:rest]], :class.to_proc.parameters, bug11845) + assert_equal([[:req], [:rest]], :class.to_proc.parameters, bug11845) c = Class.new {define_method(:klass, :class.to_proc)} m = c.instance_method(:klass) assert_nil(m.source_location, bug11845) - assert_equal([[:rest]], m.parameters, bug11845) + assert_equal([[:req], [:rest]], m.parameters, bug11845) end; end @@ -868,7 +868,7 @@ vm_caller_setup_arg_block(const rb_execution_context_t *ec, rb_control_frame_t * rb_ary_push(callback_arg, block_code); rb_ary_push(callback_arg, ref); OBJ_FREEZE_RAW(callback_arg); - func = rb_func_lambda_new(refine_sym_proc_call, callback_arg, 0, UNLIMITED_ARGUMENTS); + func = rb_func_lambda_new(refine_sym_proc_call, callback_arg, 1, UNLIMITED_ARGUMENTS); rb_hash_aset(ref, block_code, func); } block_code = func; |