diff --git a/compile.c b/compile.c index d1c86b3427..e777fba89a 100644 --- a/compile.c +++ b/compile.c @@ -2007,7 +2007,7 @@ iseq_set_use_block(rb_iseq_t *iseq) rb_vm_t *vm = GET_VM(); - if (!vm->unused_block_warning_strict) { + if (!rb_warning_category_enabled_p(RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK)) { st_data_t key = (st_data_t)rb_intern_str(body->location.label); // String -> ID st_insert(vm->unused_block_warning_table, key, 1); } diff --git a/error.c b/error.c index b6ed5d22d1..05c89fe8e8 100644 --- a/error.c +++ b/error.c @@ -86,6 +86,7 @@ static ID id_category; static ID id_deprecated; static ID id_experimental; static ID id_performance; +static ID id_strict_unused_block; static VALUE sym_category; static VALUE sym_highlight; static struct { @@ -3584,6 +3585,7 @@ Init_Exception(void) id_deprecated = rb_intern_const("deprecated"); id_experimental = rb_intern_const("experimental"); id_performance = rb_intern_const("performance"); + id_strict_unused_block = rb_intern_const("strict_unused_block"); id_top = rb_intern_const("top"); id_bottom = rb_intern_const("bottom"); id_iseq = rb_make_internal_id(); @@ -3596,12 +3598,14 @@ Init_Exception(void) st_add_direct(warning_categories.id2enum, id_deprecated, RB_WARN_CATEGORY_DEPRECATED); st_add_direct(warning_categories.id2enum, id_experimental, RB_WARN_CATEGORY_EXPERIMENTAL); st_add_direct(warning_categories.id2enum, id_performance, RB_WARN_CATEGORY_PERFORMANCE); + st_add_direct(warning_categories.id2enum, id_strict_unused_block, RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK); warning_categories.enum2id = rb_init_identtable(); st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_NONE, 0); st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_DEPRECATED, id_deprecated); st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_EXPERIMENTAL, id_experimental); st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_PERFORMANCE, id_performance); + st_add_direct(warning_categories.enum2id, RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK, id_strict_unused_block); } void diff --git a/include/ruby/internal/error.h b/include/ruby/internal/error.h index cd37f4461a..3ff885b2b1 100644 --- a/include/ruby/internal/error.h +++ b/include/ruby/internal/error.h @@ -53,6 +53,9 @@ typedef enum { /** Warning is for performance issues (not enabled by -w). */ RB_WARN_CATEGORY_PERFORMANCE, + /** Warning is for checking unused block strictly */ + RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK, + RB_WARN_CATEGORY_DEFAULT_BITS = ( (1U << RB_WARN_CATEGORY_DEPRECATED) | (1U << RB_WARN_CATEGORY_EXPERIMENTAL) | @@ -62,6 +65,7 @@ typedef enum { (1U << RB_WARN_CATEGORY_DEPRECATED) | (1U << RB_WARN_CATEGORY_EXPERIMENTAL) | (1U << RB_WARN_CATEGORY_PERFORMANCE) | + (1U << RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK) | 0) } rb_warning_category_t; diff --git a/ruby.c b/ruby.c index e95c01e8d0..6f32f11b57 100644 --- a/ruby.c +++ b/ruby.c @@ -398,6 +398,7 @@ usage(const char *name, int help, int highlight, int columns) M("deprecated", "", "Deprecated features."), M("experimental", "", "Experimental features."), M("performance", "", "Performance issues."), + M("strict_unused_block", "", "Warning unused block strictly"), }; #if USE_RJIT extern const struct ruby_opt_message rb_rjit_option_messages[]; @@ -1233,6 +1234,9 @@ proc_W_option(ruby_cmdline_options_t *opt, const char *s, int *warning) else if (NAME_MATCH_P("performance", s, len)) { bits = 1U << RB_WARN_CATEGORY_PERFORMANCE; } + else if (NAME_MATCH_P("strict_unused_block", s, len)) { + bits = 1U << RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK; + } else { rb_warn("unknown warning category: '%s'", s); } diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb index 55f38d3012..0a3d2990fc 100644 --- a/test/ruby/test_rubyoptions.rb +++ b/test/ruby/test_rubyoptions.rb @@ -118,7 +118,7 @@ class TestRubyOptions < Test::Unit::TestCase assert_in_out_err(%w(-We) + ['p $-W'], "", %w(2), []) assert_in_out_err(%w(-w -W0 -e) + ['p $-W'], "", %w(0), []) - categories = {deprecated: 1, experimental: 0, performance: 2} + categories = {deprecated: 1, experimental: 0, performance: 2, strict_unused_block: 3} assert_equal categories.keys.sort, Warning.categories.sort categories.each do |category, level| diff --git a/vm.c b/vm.c index 54bbf4d7fd..3e9de4d215 100644 --- a/vm.c +++ b/vm.c @@ -4271,12 +4271,6 @@ Init_BareVM(void) vm->constant_cache = rb_id_table_create(0); vm->unused_block_warning_table = st_init_numtable(); - // TODO: remove before Ruby 3.4.0 release - const char *s = getenv("RUBY_TRY_UNUSED_BLOCK_WARNING_STRICT"); - if (s && strcmp(s, "1") == 0) { - vm->unused_block_warning_strict = true; - } - // setup main thread th->nt = ZALLOC(struct rb_native_thread); th->vm = vm; diff --git a/vm_core.h b/vm_core.h index 459e800e39..398f771121 100644 --- a/vm_core.h +++ b/vm_core.h @@ -799,7 +799,6 @@ typedef struct rb_vm_struct { struct rb_id_table *negative_cme_table; st_table *overloaded_cme_table; // cme -> overloaded_cme st_table *unused_block_warning_table; - bool unused_block_warning_strict; // This id table contains a mapping from ID to ICs. It does this with ID // keys and nested st_tables as values. The nested tables have ICs as keys diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 71583e60cd..bb33d42996 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -3035,6 +3035,7 @@ warn_unused_block(const rb_callable_method_entry_t *cme, const rb_iseq_t *iseq, rb_vm_t *vm = GET_VM(); st_table *dup_check_table = vm->unused_block_warning_table; st_data_t key; + bool strict_unused_block = rb_warning_category_enabled_p(RB_WARN_CATEGORY_STRICT_UNUSED_BLOCK); union { VALUE v; @@ -3046,7 +3047,7 @@ warn_unused_block(const rb_callable_method_entry_t *cme, const rb_iseq_t *iseq, }; // relax check - if (!vm->unused_block_warning_strict) { + if (!strict_unused_block) { key = (st_data_t)cme->def->original_id; if (st_lookup(dup_check_table, key, NULL)) { @@ -3072,16 +3073,16 @@ warn_unused_block(const rb_callable_method_entry_t *cme, const rb_iseq_t *iseq, if (st_insert(dup_check_table, key, 1)) { // already shown } - else { + else if (RTEST(ruby_verbose) || strict_unused_block) { VALUE m_loc = rb_method_entry_location((const rb_method_entry_t *)cme); VALUE name = rb_gen_method_name(cme->defined_class, ISEQ_BODY(iseq)->location.base_label); if (!NIL_P(m_loc)) { - rb_warning("the block passed to '%"PRIsVALUE"' defined at %"PRIsVALUE":%"PRIsVALUE" may be ignored", - name, RARRAY_AREF(m_loc, 0), RARRAY_AREF(m_loc, 1)); + rb_warn("the block passed to '%"PRIsVALUE"' defined at %"PRIsVALUE":%"PRIsVALUE" may be ignored", + name, RARRAY_AREF(m_loc, 0), RARRAY_AREF(m_loc, 1)); } else { - rb_warning("the block may be ignored because '%"PRIsVALUE"' does not use a block", name); + rb_warn("the block may be ignored because '%"PRIsVALUE"' does not use a block", name); } } }