зеркало из https://github.com/github/ruby.git
Do not apply anon_rest optimization when passed array uses keyword-flagged hash
The optimization sets args->rest_dupped to avoid allocating an array, but this is not safe if the splat array ends in a keyword flagged hash. Unset args->rest_dupped in this case. Fixes [Bug #20388]
This commit is contained in:
Родитель
a2ac28d8ab
Коммит
2dbcc123f4
|
@ -2835,6 +2835,19 @@ class TestKeywordArguments < Test::Unit::TestCase
|
|||
assert_equal({a: 1}, kw)
|
||||
end
|
||||
|
||||
def test_anon_splat_ruby2_keywords_bug_20388
|
||||
extend(Module.new{def process(action, ...) 1 end})
|
||||
extend(Module.new do
|
||||
def process(action, *args)
|
||||
args.freeze
|
||||
super
|
||||
end
|
||||
ruby2_keywords :process
|
||||
end)
|
||||
|
||||
assert_equal(1, process(:foo, bar: :baz))
|
||||
end
|
||||
|
||||
def test_top_ruby2_keywords
|
||||
assert_in_out_err([], <<-INPUT, ["[1, 2, 3]", "{:k=>1}"], [])
|
||||
def bar(*a, **kw)
|
||||
|
|
|
@ -687,6 +687,9 @@ setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * co
|
|||
rest_last = rb_hash_dup(rest_last);
|
||||
kw_flag |= VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT;
|
||||
|
||||
// Unset rest_dupped set by anon_rest as we may need to modify splat in this case
|
||||
args->rest_dupped = false;
|
||||
|
||||
if (ignore_keyword_hash_p(rest_last, iseq, &kw_flag, &converted_keyword_hash)) {
|
||||
arg_rest_dup(args);
|
||||
rb_ary_pop(args->rest);
|
||||
|
|
Загрузка…
Ссылка в новой задаче