diff --git a/error.c b/error.c index e662b4f08a..a70d021484 100644 --- a/error.c +++ b/error.c @@ -144,6 +144,9 @@ rb_warning_category_from_name(VALUE category) if (category == ID2SYM(rb_intern("deprecated"))) { cat = RB_WARN_CATEGORY_DEPRECATED; } + else if (category == ID2SYM(rb_intern("experimental"))) { + cat = RB_WARN_CATEGORY_EXPERIMENTAL; + } else { rb_raise(rb_eArgError, "unknown category: %"PRIsVALUE, category); } diff --git a/internal.h b/internal.h index 2812b631be..baefb36c02 100644 --- a/internal.h +++ b/internal.h @@ -1558,6 +1558,7 @@ PRINTF_ARGS(void rb_syserr_enc_warning(int err, rb_encoding *enc, const char *fm typedef enum { RB_WARN_CATEGORY_NONE, RB_WARN_CATEGORY_DEPRECATED, + RB_WARN_CATEGORY_EXPERIMENTAL, } rb_warning_category_t; rb_warning_category_t rb_warning_category_from_name(VALUE category); bool rb_warning_category_enabled_p(rb_warning_category_t category); diff --git a/parse.y b/parse.y index 3aaa29111a..6d9bfc9f41 100644 --- a/parse.y +++ b/parse.y @@ -11457,7 +11457,8 @@ new_case3(struct parser_params *p, NODE *val, NODE *pat, const YYLTYPE *loc) { NODE *node = NEW_CASE3(val, pat, loc); - rb_warn0L(nd_line(node), "Pattern matching is experimental, and the behavior may change in future versions of Ruby!"); + if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL)) + rb_warn0L(nd_line(node), "Pattern matching is experimental, and the behavior may change in future versions of Ruby!"); return node; } diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index b1f4681ac5..df7a4e7cf5 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -1266,6 +1266,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| assert_raise(TypeError) {Warning[nil]} assert_raise(ArgumentError) {Warning[:XXXX]} assert_include([true, false], Warning[:deprecated]) + assert_include([true, false], Warning[:experimental]) end def test_undefined_backtrace diff --git a/test/ruby/test_pattern_matching.rb b/test/ruby/test_pattern_matching.rb index 5308ec3281..dc72aa029c 100644 --- a/test/ruby/test_pattern_matching.rb +++ b/test/ruby/test_pattern_matching.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'test/unit' -verbose, $VERBOSE = $VERBOSE, nil # suppress "warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!" +experimental, Warning[:experimental] = Warning[:experimental], false # suppress "warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!" eval "\n#{<<~'END_of_GUARD'}", binding, __FILE__, __LINE__ class TestPatternMatching < Test::Unit::TestCase class C @@ -92,7 +92,8 @@ class TestPatternMatching < Test::Unit::TestCase end assert_block do - verbose, $VERBOSE = $VERBOSE, nil # suppress "warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!" + # suppress "warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!" + experimental, Warning[:experimental] = Warning[:experimental], false eval(%q{ case true in a @@ -100,7 +101,7 @@ class TestPatternMatching < Test::Unit::TestCase end }) ensure - $VERBOSE = verbose + Warning[:experimental] = experimental end assert_block do @@ -1274,6 +1275,23 @@ END 1 in a: }, /unexpected/, '[ruby-core:95098]') end + + def assert_experimental_warning(code) + w = Warning[:experimental] + + Warning[:experimental] = false + assert_warn('') {eval(code)} + + Warning[:experimental] = true + assert_warn(/Pattern matching is experimental/) {eval(code)} + ensure + Warning[:experimental] = w + end + + def test_experimental_warning + assert_experimental_warning("case 0; in 0; end") + assert_experimental_warning("0 in 0") + end end END_of_GUARD -$VERBOSE = verbose +Warning[:experimental] = experimental