[PRISM] Implement unused block warning

Related: ruby/prism#2935
This commit is contained in:
eileencodes 2024-08-20 13:34:08 -04:00 коммит произвёл Kevin Newton
Родитель e15b454bc3
Коммит 7ad74d1686
3 изменённых файлов: 10 добавлений и 3 удалений

1
iseq.c
Просмотреть файл

@ -1030,7 +1030,6 @@ pm_iseq_new_with_opt(pm_scope_node_t *node, VALUE name, VALUE path, VALUE realpa
{ {
rb_iseq_t *iseq = iseq_alloc(); rb_iseq_t *iseq = iseq_alloc();
ISEQ_BODY(iseq)->prism = true; ISEQ_BODY(iseq)->prism = true;
ISEQ_BODY(iseq)->param.flags.use_block = true; // unused block warning is not supported yet
rb_compile_option_t next_option; rb_compile_option_t next_option;
if (!option) option = &COMPILE_OPTION_DEFAULT; if (!option) option = &COMPILE_OPTION_DEFAULT;

Просмотреть файл

@ -3825,6 +3825,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
case PM_YIELD_NODE: case PM_YIELD_NODE:
PUSH_INSN(ret, location, putnil); PUSH_INSN(ret, location, putnil);
PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_YIELD), 0, PUSH_VAL(DEFINED_YIELD)); PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_YIELD), 0, PUSH_VAL(DEFINED_YIELD));
iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq);
return; return;
case PM_SUPER_NODE: case PM_SUPER_NODE:
case PM_FORWARDING_SUPER_NODE: case PM_FORWARDING_SUPER_NODE:
@ -6962,6 +6963,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
PUSH_LABEL(ret, retry_label); PUSH_LABEL(ret, retry_label);
} }
else {
iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq);
}
PUSH_INSN(ret, location, putself); PUSH_INSN(ret, location, putself);
int flag = VM_CALL_ZSUPER | VM_CALL_SUPER | VM_CALL_FCALL; int flag = VM_CALL_ZSUPER | VM_CALL_SUPER | VM_CALL_FCALL;
@ -8994,6 +8998,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
if (parameters_node->block) { if (parameters_node->block) {
body->param.block_start = local_index; body->param.block_start = local_index;
body->param.flags.has_block = true; body->param.flags.has_block = true;
iseq_set_use_block(iseq);
pm_constant_id_t name = ((const pm_block_parameter_node_t *) parameters_node->block)->name; pm_constant_id_t name = ((const pm_block_parameter_node_t *) parameters_node->block)->name;
@ -9549,6 +9554,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_scope_node_destroy(&next_scope_node); pm_scope_node_destroy(&next_scope_node);
} }
if (!cast->block) {
iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq);
}
if ((flags & VM_CALL_ARGS_BLOCKARG) && (flags & VM_CALL_KW_SPLAT) && !(flags & VM_CALL_KW_SPLAT_MUT)) { if ((flags & VM_CALL_ARGS_BLOCKARG) && (flags & VM_CALL_KW_SPLAT) && !(flags & VM_CALL_KW_SPLAT_MUT)) {
PUSH_INSN(args, location, splatkw); PUSH_INSN(args, location, splatkw);
} }
@ -9681,6 +9690,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
} }
PUSH_INSN1(ret, location, invokeblock, new_callinfo(iseq, 0, argc, flags, keywords, FALSE)); PUSH_INSN1(ret, location, invokeblock, new_callinfo(iseq, 0, argc, flags, keywords, FALSE));
iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq);
if (popped) PUSH_INSN(ret, location, pop); if (popped) PUSH_INSN(ret, location, pop);
int level = 0; int level = 0;

Просмотреть файл

@ -887,8 +887,6 @@ class TestISeq < Test::Unit::TestCase
def test_unused_param def test_unused_param
a = RubyVM::InstructionSequence.of(method(:block_using_method)).to_a a = RubyVM::InstructionSequence.of(method(:block_using_method)).to_a
omit 'TODO: Prism' if a.dig(4, :parser) != :"parse.y"
assert_equal true, a.dig(11, :use_block) assert_equal true, a.dig(11, :use_block)
b = RubyVM::InstructionSequence.of(method(:block_unused_method)).to_a b = RubyVM::InstructionSequence.of(method(:block_unused_method)).to_a