fix lambda's warning and tests

There are warning condition bugs and test bugs.
b53ccb9c69abd24e3bdad66cbe4c7e7480eaef16
This commit is contained in:
Koichi Sasada 2020-12-12 06:29:11 +09:00
parent d741c77b5f
commit 124321e0c7
2 changed files with 35 additions and 23 deletions

50
proc.c
View File

@ -847,6 +847,34 @@ rb_block_lambda(void)
return proc_new(rb_cProc, TRUE, FALSE); return proc_new(rb_cProc, TRUE, FALSE);
} }
static void
f_lambda_warn(void)
{
rb_control_frame_t *cfp = GET_EC()->cfp;
VALUE block_handler = rb_vm_frame_block_handler(cfp);
if (block_handler != VM_BLOCK_HANDLER_NONE) {
switch (vm_block_handler_type(block_handler)) {
case block_handler_type_iseq:
if (RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)->ep == VM_BH_TO_ISEQ_BLOCK(block_handler)->ep) {
return;
}
break;
case block_handler_type_symbol:
return;
case block_handler_type_proc:
if (rb_proc_lambda_p(VM_BH_TO_PROC(block_handler))) {
return;
}
break;
case block_handler_type_ifunc:
break;
}
}
rb_warn_deprecated("lambda without a literal block", "the proc without lambda");
}
/* /*
* call-seq: * call-seq:
* lambda { |...| block } -> a_proc * lambda { |...| block } -> a_proc
@ -858,27 +886,7 @@ rb_block_lambda(void)
static VALUE static VALUE
f_lambda(VALUE _) f_lambda(VALUE _)
{ {
rb_control_frame_t *cfp = GET_EC()->cfp; f_lambda_warn();
VALUE block_handler = rb_vm_frame_block_handler(cfp);
if (block_handler != VM_BLOCK_HANDLER_NONE) {
switch (vm_block_handler_type(block_handler)) {
case block_handler_type_iseq:
if (RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)->ep == VM_BH_TO_ISEQ_BLOCK(block_handler)->ep) {
break;
}
case block_handler_type_symbol:
break;
case block_handler_type_proc:
if (rb_proc_lambda_p(VM_BH_TO_PROC(block_handler))) {
break;
}
case block_handler_type_ifunc:
rb_warn_deprecated("lambda without a literal block", "the proc without lambda");
break;
}
}
return rb_block_lambda(); return rb_block_lambda();
} }

View File

@ -316,16 +316,20 @@ class TestProc < Test::Unit::TestCase
lambda(&b) lambda(&b)
end end
def_lambda_warning 'test_lambda_warning_pass_symbol_proc', '' do
lambda(&:to_s)
end
def_lambda_warning 'test_lambda_warning_pass_proc', /deprecated/ do def_lambda_warning 'test_lambda_warning_pass_proc', /deprecated/ do
b = proc{} b = proc{}
lambda(&b) lambda(&b)
end end
def_lambda_warning 'test_lambda_warning_pass_proc', /deprecated/ do def_lambda_warning 'test_lambda_warning_pass_block', /deprecated/ do
helper_test_warn_lamda_with_passed_block{} helper_test_warn_lamda_with_passed_block{}
end end
def_lambda_warning 'test_lambda_warning_pass_proc', '' do def_lambda_warning 'test_lambda_warning_pass_block_symbol_proc', '' do
# Symbol#to_proc returns lambda # Symbol#to_proc returns lambda
helper_test_warn_lamda_with_passed_block(&:to_s) helper_test_warn_lamda_with_passed_block(&:to_s)
end end