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:
parent
a2ac28d8ab
commit
2dbcc123f4
@ -2835,6 +2835,19 @@ class TestKeywordArguments < Test::Unit::TestCase
|
|||||||
assert_equal({a: 1}, kw)
|
assert_equal({a: 1}, kw)
|
||||||
end
|
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
|
def test_top_ruby2_keywords
|
||||||
assert_in_out_err([], <<-INPUT, ["[1, 2, 3]", "{:k=>1}"], [])
|
assert_in_out_err([], <<-INPUT, ["[1, 2, 3]", "{:k=>1}"], [])
|
||||||
def bar(*a, **kw)
|
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);
|
rest_last = rb_hash_dup(rest_last);
|
||||||
kw_flag |= VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT;
|
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)) {
|
if (ignore_keyword_hash_p(rest_last, iseq, &kw_flag, &converted_keyword_hash)) {
|
||||||
arg_rest_dup(args);
|
arg_rest_dup(args);
|
||||||
rb_ary_pop(args->rest);
|
rb_ary_pop(args->rest);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user