aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-07-04 05:42:04 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-07-04 05:42:04 +0000
commit872bba6de3aea080d2aa78249d5a3090bd0aaeed (patch)
tree0204642c83abd4a10bd02fb5965f47f213c005a9
parent95f396fdd8c6bdf3304a934e4a6d624867fd0198 (diff)
downloadruby-872bba6de3aea080d2aa78249d5a3090bd0aaeed.tar.gz
vm_args.c: improve keyword argument errors
* vm_args.c (argument_arity_error): improve required keyword argument errors when non-keyword arguments given. [ruby-core:79439] [Bug #13196] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59259 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--test/ruby/test_keyword.rb13
-rw-r--r--vm_args.c21
2 files changed, 33 insertions, 1 deletions
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index f10412e6cd..4c99a3212d 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -641,4 +641,17 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal(x, result)
assert_kind_of(klass, result, bug12884)
end
+
+ def test_arity_error_message
+ obj = Object.new
+ def obj.t(x:) end
+ assert_raise_with_message(ArgumentError, /required keyword: x\)/) do
+ obj.t(42)
+ end
+ obj = Object.new
+ def obj.t(x:, y:, z: nil) end
+ assert_raise_with_message(ArgumentError, /required keywords: x, y\)/) do
+ obj.t(42)
+ end
+ end
end
diff --git a/vm_args.c b/vm_args.c
index 59bd87ebf0..898301ce49 100644
--- a/vm_args.c
+++ b/vm_args.c
@@ -719,7 +719,26 @@ raise_argument_error(rb_thread_t *th, const rb_iseq_t *iseq, const VALUE exc)
static void
argument_arity_error(rb_thread_t *th, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc)
{
- raise_argument_error(th, iseq, rb_arity_error_new(miss_argc, min_argc, max_argc));
+ VALUE exc = rb_arity_error_new(miss_argc, min_argc, max_argc);
+ if (iseq->body->param.flags.has_kw) {
+ const struct rb_iseq_param_keyword *const kw = iseq->body->param.keyword;
+ const ID *keywords = kw->table;
+ int req_key_num = kw->required_num;
+ if (req_key_num > 0) {
+ static const char required[] = "; required keywords";
+ VALUE mesg = rb_attr_get(exc, idMesg);
+ rb_str_resize(mesg, RSTRING_LEN(mesg)-1);
+ rb_str_cat(mesg, required, sizeof(required) - 1 - (req_key_num == 1));
+ rb_str_cat_cstr(mesg, ":");
+ do {
+ rb_str_cat_cstr(mesg, " ");
+ rb_str_append(mesg, rb_id2str(*keywords++));
+ rb_str_cat_cstr(mesg, ",");
+ } while (--req_key_num);
+ RSTRING_PTR(mesg)[RSTRING_LEN(mesg)-1] = ')';
+ }
+ }
+ raise_argument_error(th, iseq, exc);
}
static void