diff options
author | Koichi Sasada <ko1@atdot.net> | 2024-04-17 19:46:48 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2024-04-17 20:26:49 +0900 |
commit | e9d7478dedbd2b57530bc17efe8a9db9b8b2f280 (patch) | |
tree | c41d4f58e25d3ca4532a60247c6019f6df767300 /compile.c | |
parent | 6ade36c06b7cef948099b8f5f483763498705d12 (diff) | |
download | ruby-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.c | 23 |
1 files changed, 18 insertions, 5 deletions
@@ -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); |