aboutsummaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2024-04-17 19:46:48 +0900
committerKoichi Sasada <ko1@atdot.net>2024-04-17 20:26:49 +0900
commite9d7478dedbd2b57530bc17efe8a9db9b8b2f280 (patch)
treec41d4f58e25d3ca4532a60247c6019f6df767300 /compile.c
parent6ade36c06b7cef948099b8f5f483763498705d12 (diff)
downloadruby-e9d7478dedbd2b57530bc17efe8a9db9b8b2f280.tar.gz
relax unused block warning for duck typing
if a method `foo` uses a block, other (unrelated) method `foo` can receives a block. So try to relax the unused block warning condition. ```ruby class C0 def f = yield end class C1 < C0 def f = nil end [C0, C1].f{ block } # do not warn ```
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/compile.c b/compile.c
index b980d6a32c..853fadf5b0 100644
--- a/compile.c
+++ b/compile.c
@@ -1998,6 +1998,19 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
return arg_size;
}
+static void
+iseq_set_use_block(rb_iseq_t *iseq)
+{
+ struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
+ if (!body->param.flags.use_block) {
+ body->param.flags.use_block = 1;
+
+ rb_vm_t *vm = GET_VM();
+ st_data_t key = (st_data_t)rb_intern_str(body->location.label); // String -> ID
+ st_insert(vm->unused_block_warning_table, key, 1);
+ }
+}
+
static int
iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *const node_args)
{
@@ -2099,7 +2112,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons
if (block_id) {
body->param.block_start = arg_size++;
body->param.flags.has_block = TRUE;
- body->param.flags.use_block = 1;
+ iseq_set_use_block(iseq);
}
iseq_calc_param_size(iseq);
@@ -5920,7 +5933,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
ADD_INSN(ret, line_node, putnil);
ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_YIELD), 0,
PUSH_VAL(DEFINED_YIELD));
- ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq)->param.flags.use_block = 1;
+ iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq);
return;
case NODE_BACK_REF:
@@ -8632,7 +8645,7 @@ compile_builtin_attr(rb_iseq_t *iseq, const NODE *node)
ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_INLINE_BLOCK;
}
else if (strcmp(RSTRING_PTR(string), "use_block") == 0) {
- ISEQ_BODY(iseq)->param.flags.use_block = 1;
+ iseq_set_use_block(iseq);
}
else {
goto unknown_arg;
@@ -9481,7 +9494,7 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
}
if (use_block && parent_block == NULL) {
- ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq)->param.flags.use_block = 1;
+ iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq);
}
flag |= VM_CALL_SUPER | VM_CALL_FCALL;
@@ -9527,7 +9540,7 @@ compile_yield(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
ADD_SEQ(ret, args);
ADD_INSN1(ret, node, invokeblock, new_callinfo(iseq, 0, FIX2INT(argc), flag, keywords, FALSE));
- ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq)->param.flags.use_block = 1;
+ iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq);
if (popped) {
ADD_INSN(ret, node, pop);