Add back checks for empty kw splat with tests (#4405)

This reverts commit a224ce8150.
Turns out the checks are needed to handle splatting an array with an
empty ruby2 keywords hash.
This commit is contained in:
Alan Wu 2021-04-23 22:17:20 -04:00 коммит произвёл GitHub
Родитель 1f2b5c6dfe
Коммит dee58d7ae7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 22 добавлений и 0 удалений

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

@ -2411,6 +2411,13 @@ class TestKeywordArguments < Test::Unit::TestCase
args
end
def empty_method
end
def opt(arg = :opt)
arg
end
ruby2_keywords def foo_dbar(*args)
dbar(*args)
end
@ -2419,6 +2426,16 @@ class TestKeywordArguments < Test::Unit::TestCase
dbaz(*args)
end
ruby2_keywords def clear_last_empty_method(*args)
args.last.clear
empty_method(*args)
end
ruby2_keywords def clear_last_opt(*args)
args.last.clear
opt(*args)
end
define_method(:dbar) do |*args, **kw|
[args, kw]
end
@ -2653,6 +2670,9 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([[1, h1], {}], o.foo(:pass_bar, 1, :a=>1))
assert_equal([[1, h1], {}], o.foo(:pass_cfunc, 1, :a=>1))
assert_equal(:opt, o.clear_last_opt(a: 1))
assert_nothing_raised(ArgumentError) { o.clear_last_empty_method(a: 1) }
assert_warn(/Skipping set of ruby2_keywords flag for bar \(method accepts keywords or method does not accept argument splat\)/) do
assert_nil(c.send(:ruby2_keywords, :bar))
end

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

@ -2412,6 +2412,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
if (LIKELY(rb_simple_iseq_p(iseq))) {
rb_control_frame_t *cfp = ec->cfp;
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
if (calling->argc != iseq->body->param.lead_num) {
argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
@ -2425,6 +2426,7 @@ vm_callee_setup_arg(rb_execution_context_t *ec, struct rb_calling_info *calling,
else if (rb_iseq_only_optparam_p(iseq)) {
rb_control_frame_t *cfp = ec->cfp;
CALLER_SETUP_ARG(cfp, calling, ci);
CALLER_REMOVE_EMPTY_KW_SPLAT(cfp, calling, ci);
const int lead_num = iseq->body->param.lead_num;
const int opt_num = iseq->body->param.opt_num;