1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
Nobuyoshi Nakada 2020-02-22 10:40:25 +09:00
parent 31748e69c8
commit 5b29ea0845
No known key found for this signature in database
GPG key ID: 4BC7D6DF58D8DF60
4 changed files with 19 additions and 8 deletions

3
proc.c
View file

@ -1091,7 +1091,8 @@ rb_vm_block_min_max_arity(const struct rb_block *block, int *max)
return ifunc->argc.min; return ifunc->argc.min;
} }
case block_type_symbol: case block_type_symbol:
break; *max = UNLIMITED_ARGUMENTS;
return 1;
} }
*max = UNLIMITED_ARGUMENTS; *max = UNLIMITED_ARGUMENTS;
return 0; return 0;

View file

@ -12,18 +12,20 @@ describe "Symbol#to_proc" do
:to_s.to_proc.call(obj).should == "Received #to_s" :to_s.to_proc.call(obj).should == "Received #to_s"
end 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 = :to_s.to_proc
pr.arity.should == -1 pr.arity.should == expected_arity
end end
it "raises an ArgumentError when calling #call on the Proc without receiver" do 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") -> { :object_id.to_proc.call }.should raise_error(ArgumentError, "no receiver given")
end 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 = :to_s.to_proc
pr.parameters.should == [[:rest]] pr.parameters.should == expected_parameters
end end
it "passes along the block passed to Proc#call" do it "passes along the block passed to Proc#call" do

View file

@ -157,6 +157,10 @@ class TestSymbol < Test::Unit::TestCase
assert_predicate(:itself.to_proc, :lambda?) assert_predicate(:itself.to_proc, :lambda?)
end end
def test_to_proc_arity
assert_equal(-2, :itself.to_proc.arity)
end
def test_to_proc_call_with_symbol_proc def test_to_proc_call_with_symbol_proc
first = 1 first = 1
bug11594 = "[ruby-core:71088] [Bug #11594] corrupted the first local variable" 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?) assert_predicate(_test_to_proc_with_refinements_call(&:hoge), :lambda?)
end 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) def self._test_to_proc_arg_with_refinements_call(&block)
block.call TestToPRocArgWithRefinements.new block.call TestToPRocArgWithRefinements.new
end end
@ -230,11 +238,11 @@ class TestSymbol < Test::Unit::TestCase
begin; begin;
bug11845 = '[ruby-core:72381] [Bug #11845]' bug11845 = '[ruby-core:72381] [Bug #11845]'
assert_nil(:class.to_proc.source_location, bug11845) 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)} c = Class.new {define_method(:klass, :class.to_proc)}
m = c.instance_method(:klass) m = c.instance_method(:klass)
assert_nil(m.source_location, bug11845) assert_nil(m.source_location, bug11845)
assert_equal([[:rest]], m.parameters, bug11845) assert_equal([[:req], [:rest]], m.parameters, bug11845)
end; end;
end end

View file

@ -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, block_code);
rb_ary_push(callback_arg, ref); rb_ary_push(callback_arg, ref);
OBJ_FREEZE_RAW(callback_arg); 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); rb_hash_aset(ref, block_code, func);
} }
block_code = func; block_code = func;