`super(){}`, `super{}` and `super(&b)` doesn't use the given
block so warn unused block warning when calling a method which
doesn't use block with above `super` expressions.

e.g.: `def f = super{B1}` (warn on `f{B2}` because `B2` is not used.
This commit is contained in:
Koichi Sasada 2024-04-15 17:06:03 +09:00
Родитель 145cced9bc
Коммит 9a57b04703
2 изменённых файлов: 31 добавлений и 17 удалений

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

@ -9369,10 +9369,10 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
unsigned int flag = 0;
struct rb_callinfo_kwarg *keywords = NULL;
const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
int use_block = 1;
INIT_ANCHOR(args);
ISEQ_COMPILE_DATA(iseq)->current_block = NULL;
ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq)->param.flags.use_block = 1;
if (type == NODE_SUPER) {
VALUE vargc = setup_args(iseq, args, RNODE_SUPER(node)->nd_args, &flag, &keywords);
@ -9381,6 +9381,10 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) {
ADD_INSN(args, node, splatkw);
}
if (flag & VM_CALL_ARGS_BLOCKARG) {
use_block = 0;
}
}
else {
/* NODE_ZSUPER */
@ -9474,6 +9478,10 @@ 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;
}
flag |= VM_CALL_SUPER | VM_CALL_FCALL;
if (type == NODE_ZSUPER) flag |= VM_CALL_ZSUPER;
ADD_INSN(ret, node, putself);

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

@ -1663,28 +1663,34 @@ class TestMethod < Test::Unit::TestCase
assert_in_out_err '-w', <<-'RUBY' do |_out, err, _status|
class C0
def foo = nil
def bar = nil
def baz = nil
def qux = nil
def f1 = nil
def f2 = nil
def f3 = nil
def f4 = nil
def f5 = nil
def f6 = nil
end
class C1 < C0
def foo = super
def bar = super()
def baz(&_) = super(&_)
def qux = super(&nil)
def f1 = super # zsuper / use
def f2 = super() # super / use
def f3(&_) = super(&_) # super / use
def f4 = super(&nil) # super / unuse
def f5 = super(){} # super / unuse
def f6 = super{} # zsuper / unuse
end
C1.new.foo{} # no warning
C1.new.bar{} # no warning
C1.new.baz{} # no warning
# C1.new.qux{} # TODO: warning line:16 but not supported yet.
C1.new.f1{} # no warning
C1.new.f2{} # no warning
C1.new.f3{} # no warning
C1.new.f4{} # warning
C1.new.f5{} # warning
C1.new.f6{} # warning
RUBY
assert_equal 0, err.size
# TODO
# assert_equal 1, err.size
# assert_match(/-:16: warning.+qux/, err.join)
assert_equal 3, err.size, err.join("\n")
assert_match(/-:22: warning.+f4/, err.join)
assert_match(/-:23: warning.+f5/, err.join)
assert_match(/-:24: warning.+f6/, err.join)
end
end
end