From 7ad74d1686b626b72228e3d24d5448adcfe23d48 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Tue, 20 Aug 2024 13:34:08 -0400 Subject: [PATCH] [PRISM] Implement unused block warning Related: ruby/prism#2935 --- iseq.c | 1 - prism_compile.c | 10 ++++++++++ test/ruby/test_iseq.rb | 2 -- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/iseq.c b/iseq.c index c6a521b0bd..907a7b85c2 100644 --- a/iseq.c +++ b/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(); 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; if (!option) option = &COMPILE_OPTION_DEFAULT; diff --git a/prism_compile.c b/prism_compile.c index 14c21a9941..9aa2f21972 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -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: PUSH_INSN(ret, location, putnil); PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_YIELD), 0, PUSH_VAL(DEFINED_YIELD)); + iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq); return; case PM_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); } + else { + iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq); + } PUSH_INSN(ret, location, putself); 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) { body->param.block_start = local_index; 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; @@ -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); } + 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)) { 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)); + iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq); if (popped) PUSH_INSN(ret, location, pop); int level = 0; diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index 67d6606519..b2bccb40f8 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -887,8 +887,6 @@ class TestISeq < Test::Unit::TestCase def test_unused_param 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) b = RubyVM::InstructionSequence.of(method(:block_unused_method)).to_a