Don't modify rest array when using ruby2_keywords

Previously, the rest array was modified, but it turns out that is
not necessary.  Not modifying the rest array fixes cases when the
rest array is used more than once.
This commit is contained in:
Jeremy Evans 2019-11-27 09:03:00 -08:00
Родитель 6f27fa4f7d
Коммит 299a13612e
2 изменённых файлов: 10 добавлений и 2 удалений

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

@ -2649,6 +2649,11 @@ class TestKeywordArguments < Test::Unit::TestCase
baz(*args) baz(*args)
end end
ruby2_keywords def foo_baz2(*args)
baz(*args)
baz(*args)
end
ruby2_keywords def foo_foo_bar(meth, *args) ruby2_keywords def foo_foo_bar(meth, *args)
foo_bar(meth, *args) foo_bar(meth, *args)
end end
@ -2761,6 +2766,10 @@ class TestKeywordArguments < Test::Unit::TestCase
h1 = {a: 1} h1 = {a: 1}
o = c.new o = c.new
assert_equal([1, h1], o.foo_baz2(1, :a=>1))
assert_equal([1], o.foo_baz2(1, **{}))
assert_equal([h1], o.foo_baz2(h1, **{}))
assert_equal([[1], h1], o.foo(:bar, 1, :a=>1)) assert_equal([[1], h1], o.foo(:bar, 1, :a=>1))
assert_equal([1, h1], o.foo(:baz, 1, :a=>1)) assert_equal([1, h1], o.foo(:baz, 1, :a=>1))
assert_equal([[1], h1], o.bfoo(:bar, 1, :a=>1)) assert_equal([[1], h1], o.bfoo(:bar, 1, :a=>1))

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

@ -742,7 +742,6 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
if (RB_TYPE_P(rest_last, T_HASH) && if (RB_TYPE_P(rest_last, T_HASH) &&
(((struct RHash *)rest_last)->basic.flags & RHASH_PASS_AS_KEYWORDS)) { (((struct RHash *)rest_last)->basic.flags & RHASH_PASS_AS_KEYWORDS)) {
rest_last = rb_hash_dup(rest_last); rest_last = rb_hash_dup(rest_last);
RARRAY_ASET(args->rest, len - 1, rest_last);
kw_flag |= VM_CALL_KW_SPLAT; kw_flag |= VM_CALL_KW_SPLAT;
if (iseq->body->param.flags.ruby2_keywords) { if (iseq->body->param.flags.ruby2_keywords) {
remove_empty_keyword_hash = 0; remove_empty_keyword_hash = 0;
@ -754,7 +753,7 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
} }
if (kw_flag & VM_CALL_KW_SPLAT) { if (kw_flag & VM_CALL_KW_SPLAT) {
if (len > 0 && ignore_keyword_hash_p(RARRAY_AREF(args->rest, len - 1), iseq)) { if (len > 0 && ignore_keyword_hash_p(rest_last, iseq)) {
if (given_argc != min_argc) { if (given_argc != min_argc) {
if (remove_empty_keyword_hash) { if (remove_empty_keyword_hash) {
arg_rest_dup(args); arg_rest_dup(args);