ruby-changes:50737
From: nobu <ko1@a...>
Date: Sun, 25 Mar 2018 11:22:19 +0900 (JST)
Subject: [ruby-changes:50737] nobu:r62914 (trunk): vm_args.c: warn splat to var
nobu 2018-03-25 11:22:14 +0900 (Sun, 25 Mar 2018) New Revision: 62914 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62914 Log: vm_args.c: warn splat to var * vm_args.c (setup_parameters_complex): [EXPERIMENTAL] warn when splat keyword arguments is passed as a single ordinary argument, not as a keyword rest argument. Modified files: trunk/test/ruby/test_keyword.rb trunk/vm_args.c Index: vm_args.c =================================================================== --- vm_args.c (revision 62913) +++ vm_args.c (revision 62914) @@ -509,6 +509,7 @@ setup_parameters_complex(rb_execution_co https://github.com/ruby/ruby/blob/trunk/vm_args.c#L509 const int max_argc = (iseq->body->param.flags.has_rest == FALSE) ? min_argc + iseq->body->param.opt_num : UNLIMITED_ARGUMENTS; int opt_pc = 0; int given_argc; + int kw_splat = FALSE; struct args_info args_body, *args; VALUE keyword_hash = Qnil; VALUE * const orig_sp = ec->cfp->sp; @@ -600,10 +601,12 @@ setup_parameters_complex(rb_execution_co https://github.com/ruby/ruby/blob/trunk/vm_args.c#L601 } } + if (ci->flag & VM_CALL_KW_SPLAT) { + kw_splat = !iseq->body->param.flags.has_rest; + } if (given_argc > min_argc && (iseq->body->param.flags.has_kw || iseq->body->param.flags.has_kwrest || - (!iseq->body->param.flags.has_rest && given_argc > max_argc && - (ci->flag & VM_CALL_KW_SPLAT))) && + (kw_splat && given_argc > max_argc)) && args->kw_argv == NULL) { if (args_pop_keyword_hash(args, &keyword_hash)) { given_argc--; @@ -667,6 +670,10 @@ setup_parameters_complex(rb_execution_co https://github.com/ruby/ruby/blob/trunk/vm_args.c#L670 else if (!NIL_P(keyword_hash) && RHASH_SIZE(keyword_hash) > 0) { argument_kw_error(ec, iseq, "unknown", rb_hash_keys(keyword_hash)); } + else if (kw_splat && NIL_P(keyword_hash)) { + rb_warning("passing splat keyword arguments as a single Hash" + " to `% "PRIsVALUE"'", rb_id2str(ci->mid)); + } if (iseq->body->param.flags.has_block) { if (iseq->body->local_iseq == iseq) { Index: test/ruby/test_keyword.rb =================================================================== --- test/ruby/test_keyword.rb (revision 62913) +++ test/ruby/test_keyword.rb (revision 62914) @@ -507,6 +507,7 @@ class TestKeywordArguments < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L507 m = Object.new def m.f() :ok; end def m.f2(a = nil) a; end + def m.f3(**a) a; end o = {a: 1} assert_raise_with_message(ArgumentError, /unknown keyword: a/) { m.f(**o) @@ -517,9 +518,16 @@ class TestKeywordArguments < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L518 assert_equal(:ok, m.f(*a, **o), '[ruby-core:83638] [Bug #10856]') o = {a: 42} - assert_equal({a: 42}, m.f2(**o), '[ruby-core:82280] [Bug #13791]') + assert_warning(/splat keyword/) do + assert_equal({a: 42}, m.f2(**o), '[ruby-core:82280] [Bug #13791]') + end + assert_warning('') do + assert_equal({a: 42}, m.f3(**o), 'splat to kwrest') + end - assert_equal({a: 42}, m.f2("a".to_sym => 42), '[ruby-core:82291] [Bug #13793]') + assert_warning('') do + assert_equal({a: 42}, m.f2("a".to_sym => 42), '[ruby-core:82291] [Bug #13793]') + end o = {} a = [:ok] -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/