Proc made by Hash#to_proc should be a lambda [Bug #12671]

Like `Symbol#to_proc` (f0b815dc670b61eba1daaa67a8613ac431d32b16)
This commit is contained in:
Yusuke Endoh 2020-03-16 23:32:55 +09:00
parent 304538e6ff
commit d514ba8e17
3 changed files with 16 additions and 6 deletions

8
proc.c
View File

@ -667,7 +667,7 @@ bind_location(VALUE bindval)
} }
static VALUE static VALUE
cfunc_proc_new(VALUE klass, VALUE ifunc, int8_t is_lambda) cfunc_proc_new(VALUE klass, VALUE ifunc)
{ {
rb_proc_t *proc; rb_proc_t *proc;
cfunc_proc_t *sproc; cfunc_proc_t *sproc;
@ -685,7 +685,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc, int8_t is_lambda)
/* self? */ /* self? */
RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc); RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
proc->is_lambda = is_lambda; proc->is_lambda = TRUE;
return procval; return procval;
} }
@ -736,14 +736,14 @@ MJIT_FUNC_EXPORTED VALUE
rb_func_proc_new(rb_block_call_func_t func, VALUE val) rb_func_proc_new(rb_block_call_func_t func, VALUE val)
{ {
struct vm_ifunc *ifunc = rb_vm_ifunc_proc_new(func, (void *)val); struct vm_ifunc *ifunc = rb_vm_ifunc_proc_new(func, (void *)val);
return cfunc_proc_new(rb_cProc, (VALUE)ifunc, 0); return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
} }
MJIT_FUNC_EXPORTED VALUE MJIT_FUNC_EXPORTED VALUE
rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc) rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc)
{ {
struct vm_ifunc *ifunc = rb_vm_ifunc_new(func, (void *)val, min_argc, max_argc); struct vm_ifunc *ifunc = rb_vm_ifunc_new(func, (void *)val, min_argc, max_argc);
return cfunc_proc_new(rb_cProc, (VALUE)ifunc, 1); return cfunc_proc_new(rb_cProc, (VALUE)ifunc);
} }
static const char proc_without_block[] = "tried to create Proc object without a block"; static const char proc_without_block[] = "tried to create Proc object without a block";

View File

@ -19,9 +19,17 @@ describe "Hash#to_proc" do
@proc = @hash.to_proc @proc = @hash.to_proc
end end
ruby_version_is ""..."2.8" do
it "is not a lambda" do it "is not a lambda" do
@proc.lambda?.should == false @proc.lambda?.should == false
end end
end
ruby_version_is "2.8" do
it "is a lambda" do
@proc.lambda?.should == true
end
end
it "raises ArgumentError if not passed exactly one argument" do it "raises ArgumentError if not passed exactly one argument" do
-> { -> {

View File

@ -1627,6 +1627,8 @@ class TestHash < Test::Unit::TestCase
} }
assert_equal([10, 20, 30], [1, 2, 3].map(&h)) assert_equal([10, 20, 30], [1, 2, 3].map(&h))
assert_equal(true, h.to_proc.lambda?)
end end
def test_transform_keys def test_transform_keys